颠倒一个链表的顺序 C++
2017-11-30 20:01
531 查看
首先我们定义一个头结点:
1)首先我们先用递归方法来进行处理
(1)如果一个链表为空链表,那么他的逆序还是为空
(2)如果一个链表中只有一个节点,那么他的逆序就是这个链表本身.
(3)如果一个链表的长度大于一,那么我们做如下递归.
把当前链表的除了头节点L之外的剩余节点组成的链表逆序,也就是递归调用,并得到剩余链表逆序后的头结点p,
此时将L的下一个节点的的next指向L, 并将L的next指针置空.然后返回p.
(简单来说,先是一层层寻找,找到尾结点返回给p,然后返回上一层,这时最后一个节点为L->next,将L->next的next指向现在第二层的L,然后再把L的next置空,即完成了第一次翻转,然后再返回给p;把这次的两个结点看成最后一个,然后在倒数第三层重复反转,最后完成整个反转)
为了验证,我们还要写一个显示函数:
void display(Node*L)
{ Node*p=L;
if(p==NULL) return ;
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
下面是我的完整代码:
#include<iostream>
using namespace std;
struct Node{ int data; Node*next; };
//a是一个数组,n代表数组元素的个数
Node*createLinkList(int a[],int n)
{
if(a==NULL||n==0)
return NULL;
Node*L,*T=NULL;
for(int i=0;i<n;i++)
{
if(i==0)
{L=new Node;
L->data=a[i];
L->next=NULL;
T=L;
}else
{
Node*s=new Node;
s->data=a[i];
s->next=NULL;
T->next=s;
T=s;//结点移动
}
}
return L;
}
void display(Node*L)
{ Node*p=L;
if(p==NULL) return ;
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
Node*reverseLinkList(Node*L) { if(L==NULL) return NULL; if(L->next==NULL) return L; Node*p=reverseLinkList(L->next); L->next->next=L;//倒数第一个指向倒数第二个 L->next=NULL;//倒数第二个指针置空 return p; }
Node*noreverseLinkList(Node*L) { if(L==NULL||L->next==NULL) return L; Node*pnow=L,*pre=NULL,*nex=NULL,*tail=NULL; while(pnow!=NULL) { nex=pnow->next; if(NULL==nex){ tail=pnow;} pnow->next=pre; pre=pnow; pnow=nex; } return tail; }
int _tmain(int argc, _TCHAR* argv[])
{
int a[] = {1,2,3,4,5,6};
int b[] = {1,2,3,4,5,6,7};
Node *L = createLinkList(a,6);
display(L);
display(noreverseLinkList(L));
Node *A = createLinkList(b,7);
display(reverseLinkList(A));
system("pause");
return 0;
}
谢谢阅读。详细解读:(有图理解)http://blog.csdn.net/zhaoruixiang1111/article/details/49932603
struct Node{ int data; Node*next; };接下来我们写一个函数来创建一个链表:
//a是一个数组,n代表数组元素的个数 Node*createLinkList(int a[],int n) { if(a==NULL||n==0) return NULL; Node*L,*T=NULL; for(int i=0;i<n;i++) { if(i==0) {L=new Node; L->data=a[i]; L->next=NULL; T=L; }else { Node*s=new Node; s->data=a[i]; s->next=NULL; T->next=s; T=s;//结点移动 } } return L; }下面就开始我们的翻转方法部分
1)首先我们先用递归方法来进行处理
(1)如果一个链表为空链表,那么他的逆序还是为空
(2)如果一个链表中只有一个节点,那么他的逆序就是这个链表本身.
(3)如果一个链表的长度大于一,那么我们做如下递归.
把当前链表的除了头节点L之外的剩余节点组成的链表逆序,也就是递归调用,并得到剩余链表逆序后的头结点p,
此时将L的下一个节点的的next指向L, 并将L的next指针置空.然后返回p.
(简单来说,先是一层层寻找,找到尾结点返回给p,然后返回上一层,这时最后一个节点为L->next,将L->next的next指向现在第二层的L,然后再把L的next置空,即完成了第一次翻转,然后再返回给p;把这次的两个结点看成最后一个,然后在倒数第三层重复反转,最后完成整个反转)
Node*reverseLinkList(Node*L) { if(L==NULL) return NULL; if(L->next==NULL) return L; Node*p=reverseLinkList(L->next); L->next->next=L;//倒数第一个指向倒数第二个 L->next=NULL;//倒数第二个指针置空 return p; }2)第二种方法就不进行递归进行翻转,然而我们直接在最后翻转会出现断链,进而不能进行连续遍历,所以我们可以定义三个结点,pnow指向当前结点,pre指向它的前置,nex指向它的后驱,首先令pnow的下一个指针指向nex,然后令pnow的next拆掉并连接pre,进行翻转,这时pnow和nex之间是断开的,然后将pnow设置为前驱pre,将nex设置为pnow,即完成了一段翻转,重复到完毕即可。
Node*noreverseLinkList(Node*L) { if(L==NULL||L->next==NULL) return L; Node*pnow=L,*pre=NULL,*nex=NULL,*tail=NULL; while(pnow!=NULL) { nex=pnow->next; if(NULL==nex){ tail=pnow;} pnow->next=pre; pre=pnow; pnow=nex; } return tail; }
为了验证,我们还要写一个显示函数:
void display(Node*L)
{ Node*p=L;
if(p==NULL) return ;
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
下面是我的完整代码:
#include<iostream>
using namespace std;
struct Node{ int data; Node*next; };
//a是一个数组,n代表数组元素的个数
Node*createLinkList(int a[],int n)
{
if(a==NULL||n==0)
return NULL;
Node*L,*T=NULL;
for(int i=0;i<n;i++)
{
if(i==0)
{L=new Node;
L->data=a[i];
L->next=NULL;
T=L;
}else
{
Node*s=new Node;
s->data=a[i];
s->next=NULL;
T->next=s;
T=s;//结点移动
}
}
return L;
}
void display(Node*L)
{ Node*p=L;
if(p==NULL) return ;
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
Node*reverseLinkList(Node*L) { if(L==NULL) return NULL; if(L->next==NULL) return L; Node*p=reverseLinkList(L->next); L->next->next=L;//倒数第一个指向倒数第二个 L->next=NULL;//倒数第二个指针置空 return p; }
Node*noreverseLinkList(Node*L) { if(L==NULL||L->next==NULL) return L; Node*pnow=L,*pre=NULL,*nex=NULL,*tail=NULL; while(pnow!=NULL) { nex=pnow->next; if(NULL==nex){ tail=pnow;} pnow->next=pre; pre=pnow; pnow=nex; } return tail; }
int _tmain(int argc, _TCHAR* argv[])
{
int a[] = {1,2,3,4,5,6};
int b[] = {1,2,3,4,5,6,7};
Node *L = createLinkList(a,6);
display(L);
display(noreverseLinkList(L));
Node *A = createLinkList(b,7);
display(reverseLinkList(A));
system("pause");
return 0;
}
谢谢阅读。详细解读:(有图理解)http://blog.csdn.net/zhaoruixiang1111/article/details/49932603
相关文章推荐
- C/C++ | 27-19 写出程序把一个链表中的接点顺序倒排
- 颠倒一个链表的顺序
- 对面试题“输入n,求一个nXn矩阵,规定矩阵沿45度递增,形成一个zigzag数组(JPEG编码里取像素数据的排列顺序),请问如何用C++实现?”的理解
- java将一个数组顺序颠倒
- C语言程序设计习题1-19 编写函数reverse(s),实现字符串的倒序,并用该函数每次颠倒一个输入行中的字符顺序
- 单链表的顺序插入、删除、查找/code/c&c++
- C++线性表之顺序表和单链表
- C/C++面试之算法系列--怎样快速检测出一个巨大的单链表中是否具备死链及其位置
- c/c++:一个带迭代器的链表模板 iterator
- c++实现两有序链表合并成一个新链表
- C++实现顺序表及双向链表
- 一个线程间同步 + FIFO顺序操作链表的例子
- C/C++ | 26-17 已知一个单向链表的头,删除其某一个结点的算法
- C++ 单链表基本操作分析与实现 链表 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结
- 用一段代码实现一个链表倒序(C++实现)
- 颠倒一个句子中的词的顺序。比如: I am a student颠倒后变成:student a am I.
- 将两个已排序的链表归并成一个链表(C++面试题)
- 一个简单链表的C++实现(二)
- C++学习(一)顺序链表
- 给定一个链表的头指针,要求只遍历一次,将单链表中的元素的顺序翻转过来