前言:单链表是数据结构中非常常用的一种线性表,有很多的用法,那么我们怎样将一个单链表进行逆转呢?这也是我初学的是时候所遇到的问题之一,那么今天来跟大家分享下我总结的方法。

单链表逆转

链表的逆转,又可以成为翻转或逆置链表,表达的是同一个意思,以图1所示链表为例:

																								                                                      图1 未逆转的链表

经过逆转后得到的新链表如图2:

                                                                                                                                                       图2 逆转后的链表

通过比较图1、2可知所谓的链表逆转,其实就是将链表整体反过来,即头变成尾,为变成头,那么如何实现呢?

我们将此功能定义成一个函数,用来接收原链表的地址,然后返回逆转后链表的首地址。

函数接口定义:

LNode *Reverse(  LNode *head );

链表的定义:

typedef struct LNode{
             int  data;       
			 struct LNode *next
}LNode;			 

具体操作:

  1. 使用3个指针,逐个节点的逆转。
  2. p q两个指针分别指向想要逆转关系的两个节点。
  3. p指向前一个节点,q指向后一个节点。
  4. r指向q后余下的链表。

这里我们忽略头结点,也就是连头结点一起逆转。

进行初始化:

p=head;

q=p->next;

p->next=NULL;

这里我们先让p指向第一个节点,q指向第二个节点。然后解开他们之间的关系

让第一个的节点的next指向NULL,以便后续我们建立新的也就是逆转之后的关系。

如图:

循环部分:

在循环体我们要做的第一步是

r=q->next;

让r记录下余下链表

然后是

q->next=p;

建立新的关系让q的next指向p

最后是

p=q;

q=r

把q p分别赋予新的节点(这个过程也蕴含着解开原有关系的效果)继续上面的步骤。 下面附上我的完整代码:

#include<iostream>
#include<cstdlib>
using namespace std;

typedef struct LNode{        //链表定义 
	int data;
	struct LNode *next;
}LNode;

//链表逆转函数 
LNode *Reverse(LNode *head)  
{
	LNode *p,*q,*r;
	p=head;
    q=p->next;
    p->next=NULL;
    while(q)
    {
   	     r=q->next;
   	     q->next=p;
   	     p=q;
   	     q=r;
    }
    return p;          //返回逆转后的链表首地址 
}

//创建链表 
LNode *initList()
{
	int n;cin>>n;                                       //定义创建的节点数 
	LNode *head,*node,*end;     					    //定义头节点,普通节点,尾节点 
	head = (LNode *)malloc(sizeof(LNode)); 	            //给头节点申请内存 
	cin>>head->data;                                    //给头结点赋值 
	end = head;        									//若是空表,则头尾地址一致 
	for(int i=0;i<n-1;i++){								//利用for循环向链表中添加数据 
		node = (LNode *)malloc(sizeof(LNode));          //给普通节点申请内存空间 
		cin>>node->data;		 	                    //给数据域赋值 
		end->next = node;								//让上一个节点的数据域指向当前节点 
		end = node;     								//end指向当前节点,最终end指向尾节点 
	}
	end->next = NULL;                                   //给end的指针域置空 
	return head;   
} 

//打印链表
void printf(LNode *head)
{
	LNode *p = head;                       
	while(p != NULL){                //遍历链表并打印 
		cout<<p->data<<" ";
		p = p->next;
	}
	cout<<endl;
} 

int main()
{
	LNode *myLNode=NULL;         //创建头节点 
	myLNode=initList();          //创建链表
	cout<<endl; 
	printf(myLNode);             //打印逆转前的链表 
	myLNode=Reverse(myLNode);    //将链表进行逆转 
	printf(myLNode);             //打印逆转后的链表 
	return 0;
} 

输入输出如下:

总结:链表的逆转方法有很多,我这个也只是其中一种,其余的方法如果你们感兴趣的话可以自行查找,也希望我所提供的这种方法可以帮助到大家。