将一个链表按逆序排列,即将链头当链尾,链尾当链头。
2013-10-27 18:01
274 查看
STU *invert(STU *head){ STU *new_head=NULL,*p1,*p2,*new; do{ for(p1=head;p1->next!=NULL;p1=p1->next) p2=p1; if(new_head==NULL) { new_head=p1; new_head->next=p2; } else { new->next=p2; } new=p2; p2->next=NULL; }while(head->next!=NULL); return new_head; }
完整的代码我就不贴了,只贴用来进行逆序的函数。链表的新建和输出在前面的博客里可以找到。
谭浩强答案书上的答案可能是印刷错误,调试不出答案,我揣摩答案的思路重新整理了一下函数。
算法的思路是这样的:
第1次循环:
找到链表的最后一个结点p1和倒数第二个结点p2;
把p1当作新链头(Line 8),p2当作新链的第二个结点(Line 9),也是新链中最新的结点(Line 15);
把原来链表的最后一个结点删去(Line 16)。
这次循环完成之后,原来链表的结点少了一个,新链表的结点多了两个。
第2次循环:
找到链表的最后一个结点p1和倒数第二个结点p2,此时的p1是原先的倒数第二个结点,p2是原先的倒数第3个结点;
把p2连接在新链表的后面(Line 13),此时p2是新链中最新的结点(Line 15);
再从原来的链表删去一个结点(Line 16)。
这次循环完成之后,原来链表的结点少了一个,新链表的结点多了一个。
……
从第2次循环开始,每次是把链表中的倒数第二个结点加入到新链中。当head->next==NULL时,链表中只有一个结点,没有倒数第二个结点,所以循环结束,新链表已经产生。最后一次循环过程中,p1是指向最初链表的第二个结点,p2指向最初链表的头结点,把p2加入到新链中,同时使p2->next=NULL,成为新链的链尾。
如果知道链表的长度len的话,可以用以下更容易理解的代码:
STU *invert(STU *head){ STU *new_head=NULL,*p1,*p2,*new; int i; for(i=0;i<len;i++) { p2=head; for(p1=head;p1->next!=NULL;p1=p1->next) p2=p1; if(new_head==NULL) new_head=p1; else new->next=p1; new=p1; p2->next=NULL; } return new_head; }
循环len次,每次把链表末尾的结点加入到新链表。Line 6的目的是预防链表中只有一个结点时,p2的值为不确定的值的情况。
相关文章推荐
- 将一个链表按逆序排列,即将链头当链尾,链尾当链头。
- 将一个链表按逆序排列,即将链头当链尾,链尾当链头
- P318_1112 将链表逆序排列,即将链头当链尾,链尾当链头
- 教材答案有错误P318_1112 将链表逆序排列,即将链头当链尾,链尾当链头
- 链表逆序(递归&非递归)/倒序输出链表值/用一个递增序列构建平衡二叉搜索树/用递归的方法判断数组是不是升(降)序排列
- 将链表逆序排列的一个程序及思考的对链表依某一元素排序方法
- 2. Add Two Numbers 给定的两个链表是逆序排列的,相加后放在一个新的链表里边
- 将一个链表按逆序排列
- 已知链表的头结点head,写一个函数把这个链表逆序
- 用链表形式存储一个字符串,插入、删除某个字符,最后按正序、逆序两种方式输出字符串
- 利用迭代实现逆序排列一个数字,比如输入1232,得到2321
- 将一个升序排列的单链表和一个降序排列的单链表合并成一个升序排列的单链表(优酷土豆2014校园招聘笔试题)
- 关于链表的逆序排列!
- 基于链表:键盘输入若干个整数,按输入数据逆序建立一个带头结点的单链表
- 将两个升序排列的单链表合并为一个降序排列的单链表且不增加新的结点
- C语言 将链表中的元素在同一个链表中逆序输出
- 9.28机试 定义两个数组,首先把两个数组合并成一个新数组,然后把新数组中的所有元素逆序排列
- 将一个单向链表逆序
- 设计鲁棒性的方法:输入一个链表的头结点,逆序遍历打印该链表出来
- 一个简单的程序,统计文本文档中的单词和汉字数,逆序排列(出现频率高的排在最前面)。python实现。