对一个单链表进行逆序排列。
来源:互联网 发布:新理念外语网络教学app 编辑:程序博客网 时间:2024/05/23 07:23
对一个单链表进行逆序排列。
版权声明:本文为博主原创文章,未经博主允许不得转载。
算法:当建立好一个链表后,指针的方向是固定的,从某种意义上来说只能从head开始,每一个next都是指向下一个,即从左到右,如果要逆序排列,首先很容易想到要访问到尾节点,将其当做新的头结点,然后让它去指向倒数第二个倒数第三个等等。可问题来了,找到新的头结点到时很容易,那如果让它按照倒数第二个,倒数第三个......也就是从右至左的逆序访问呢?毕竟链表里没有哪个指针可以指向反方向的啊,研究了一下午的老谭的算法,终于想通了(在这里小小的膜拜下,确实牛逼!)。逆序的核心算法如下:首先去遍历初始链表,这个比较简单p2=p1;p1=p1->next;(其中p1主要访问下一结点,p2记录p1走过的地方),访问到最后我们就可以找到新的头结点(即这里的尾节点),然后赋值新的指针,newp=newhead=p1;接下来就是算法的经典步骤了,此时p1,newp,newhead都指向最后一个节点,而p2指向倒数第二个节点,立刻使p2->next=null;这样就等于丢掉了最后一个节点,使得p2指向了新的链表的尾节点(此时链表少了一个节点)。这是第一趟的步骤,为了找出规律,继续看第二趟,也就是说继续让p1,p2指向head(head是原链表的头结点,它一直都没有动,以方便每趟的初始化),然后去遍历链表节点,这时又可以找到最后一个节点(原链表的倒数第二个节点),然后又断开它,这时,已经断开了两个节点了,第一趟找到的是新的头结点,那么立刻连接这个第二次丢掉的节点,重新组建新链表,即newp->next=p1,这样这两个节点就连接起来了,可是这样还不够,为了遍历新的链表,得有一个指针啊,还得让newp指针过去,它现在还在新的头结点哪里呢(不用不是浪费了),让它去倒数第二个节点的地方(以方便以后的连接),结合起来就是newp=newp->next=p1;依次这样循环len次即可(len为链表节点数)。代码如下:
- #include <stdio.h>
- #include <malloc.h>
- struct stu
- {
- int num;
- struct stu *next;
- };
- void main()
- { int i;//用以遍历循环
- int len;//链表长度
- struct stu *p1,*p2,*head,*newhead,*newp;
- p1=p2=head=(struct stu*)malloc(sizeof(struct stu));
- printf("--------输入链表开始----------\n");
- printf("输入一个节点(输入0则退出):\n");
- scanf("%3d",&p1->num);
- len=1;//长度加1
- while(p1->num!=0)
- {
- p1=(struct stu*)malloc(sizeof(struct stu));//p1指向新节点
- printf("继续输入节点(输入0则退出):\n");
- scanf("%3d",&p1->num);
- if (p1->num==0)
- p2->next=NULL;//只有一个节点
- else
- {
- p2->next=p1;
- p2=p1;
- len++;}
- }
- printf("---------输出原始链表----------\n");
- p1=head;//初始化指针用以输出
- for (i=1;i<=len;i++)
- {
- printf("%3d ",p1->num);
- p1=p1->next;
- }
- printf("\n");
- printf("------对原始链表排序并输出------\n");
- for (i=1;i<=len;i++)
- {
- p1=p2=head;
- while(p1->next!=NULL)//此循环非常重要,去指向每趟尾节点
- {p2=p1;
- p1=p1->next;//此时p1指向最后一个,p2为倒数第二个,注意循环条件
- }
- if(i==1)//第一趟时,将尾节点作为新的头结点
- newhead=newp=p1;
- else
- newp=newp->next=p1;//每趟都新加入一个之前链表丢掉的节点
- p2->next=NULL;//每趟的倒数第二个节的next都指向空,等于切断了倒数第一个节点
- }
- //输出逆序后的链表
- p1=newhead;
- for (i=1;i<=len;i++)
- {printf("%4d",p1->num);
- p1=p1->next;
- }
- printf("\n");
- }
- 对一个单链表进行逆序排列。
- 对一个单链表进行逆序排列。
- 对一个单向链表进行逆序
- 对一个字符数组进行全排列
- 全排列与逆序对
- 将一个字符串逆序排列
- 不使用库函数,对字符串进行以空格划分的逆序排列.
- JAVA数组学习之一:对一维数组进行逆序排列
- 对一个字符数组的元素进行全排列
- 给定一个数组,对该数组进行全排列
- 对一个字符串逆序
- 逆序排列
- 逆序排列
- 一个用VB实现的对任意字符串进行排列并排序的函数
- 编写一个C程序对16位整数进行倒序排列.
- 简单编程(二十三)对一个二维数组a进行升序排列
- 一种基于归并排序及随机数生成器对一个给定数组进行随机排列的算法
- android中对一个集合中的数据进行乱序排列的一些方法
- [从头学数学] 第181节 数列
- 精灵王子逃出洞穴
- 第二次_r日记管理
- leetcode 19:Remove Nth Node From End of List
- 递归实现前向匹配分词
- 对一个单链表进行逆序排列。
- Android问题集锦之二十九:Cannot run program "/xx/build-tools/xx/aapt": error=2, No such file or directory
- 剑指offer—旋转字符串
- 我的感想
- fileTom3u8.bat
- 核心动画的简单理解
- 基于Nginx1.9+LuaJIT+Kafka的点播监控系统实战(上海卓越智慧树网点播监控系统)
- leetcode—— 39——Combination Sum
- linux mysql 忘记密码怎么办