颠倒一个链表的顺序

原创 2015年11月19日 20:46:14

对于颠倒一个链表的顺序这里我们介绍两种可行的方法: 递归的和非递归的.


我们先说说递归的方法:

(1)如果一个链表为空链表,那么他的逆序还是为空,也就是这个链表本身了.

(2)如果一个链表中只有一个节点,那么他的逆序就是这个链表本身.

(3)如果一个链表的长度大于一,那么我们做如下递归.

把当前链表的除了头节点(head)之外的剩余节点组成的链表逆序,也就是递归调用,并得到剩余链表逆序后的头结点(ph),

此时将head的下一个节点的的next指向head, 并将head的next指针置空.然后返回ph.


说起来比较抽象,画图模拟一下吧:

(1).(2)点很简单,我们只说(3):


我们调用函数reverse(head), 将整个链表的头部传进去.然后head不为空,且head.next不为空,那么递归调用,reverse(head.next),此时链表长度减一.程序一直递归,直至当前传入的链表长度为1时,程序返回该子链表本身,其实就只有一个节点,也就是原链表的最后一个节点,此时程序返回ph(就是唯一的那个节点)到上一次调用处,此时程序处在倒数第二层调用.情况如下

图中的ph就是最后一次递归返回的节点,head为倒数第二次递归时链表的头结点.此时如何完成节点顺序的倒置呢,如下:


该过程分为两步: 

第一步先是将head的后一个节点的next指向当前头结点.

第二部再是将head的next置为空,去掉head.next和ph之间的关系.

此时的链表变为:


然后倒数第二层递归执行完成,将ph返回给倒数第三层.情形如下:


图中框起来部分就是倒数第二层递归时已经完成逆序的部分,当前递归中应该处理此时的head与ph之间的关系

此时依然完成上面已经提到过的那两步:


此时绿线部分便是在此次循环过程中完成的工作,一次类推.直至将整个链表逆序.


程序源码:

public Node reverse(Node head){
	if (head == null){
		return head;
	}
	if (head.next == null){
		return head;
	}
	Node ph = reverse(head.next);
	head.next.next = head;
	head.next = null;
	return ph;
}


下面我们来说说非递归的方法:

非递归过程比较简单,此处仅给出实现代码:

public Node reverse1(Node head){
	if (head == null){
		return null;
	}
	Node p = head;
	Node previous = null;
	while (p.next != null){
		p.next = previous;
		previous = p;
		p = previous.next;
	}
	p.next = previous;
	return p;
}

整个过程中使用previous保存已经处理过的上一个节点,总是将当前节点的next指向上一个节点.而上一个节点恰恰就是原链表中当前节点的下一个节点,以此来实现链表的颠倒.

注意事项为头结点的上一个节点为空,因此previous应该初始化为空,还有一点就是原链表的尾会成为新链表的头,而原链表的尾部的next为空,因此需要单独处理,也就是在推出循环后,将p.next指向previous.

版权声明:本文为博主原创文章,欢迎转载

翻转链表

思想 其实就是设置两个指针 pointer1, pointer2 。同步的移动pointer1, pointer2 ,head 这3个指针。这 3 个指针的前后顺序刚好是pointer1, poi...
  • u012155875
  • u012155875
  • 2018年01月15日 19:37
  • 5

链表:顺序链表和单链表

在学习线性表之前,必须要清楚“顺序存储的线性表”和“链式存储的线性表”。 (1)顺序存储线性表         1、采用数组来存储顺序线性表的各元素。         2、基本结构: #define...
  • look122333
  • look122333
  • 2013年10月27日 20:09
  • 2294

链表原地反转

设链表节点为 [cpp] view plaincopy typedef struct tagListNode{       int data;  ...
  • xiao1ni1zi
  • xiao1ni1zi
  • 2014年04月17日 16:52
  • 1409

Java单链表反转 详细过程

Java单链表反转 Java实现单链表翻转 使用递归法实现单链表反转,使用遍历反转法:递归反转法是从后往前逆序反转指针域的指向,而遍历反转法是从前往后反转各个结点的指针域的指向。     【尊重原创,...
  • guyuealian
  • guyuealian
  • 2016年04月11日 10:36
  • 29022

单向链表反转(倒置)问题

今天遇到单向链表的反转的问题,于是静下心来好好想了一番。 解题思路如下图:假设当前创建好的链表如下:首先让头节点与第一个元素节点断开,但是要注意在断开之前需要用p指针指向第一个元素节点来保存第一个元...
  • blioo
  • blioo
  • 2017年03月14日 19:40
  • 5812

单链表倒置算法

先上代码。 void reverse(list *head) { list *p, *tmp; p = head->next;  //p指向当前正在处理的节点 ...
  • hjason2042
  • hjason2042
  • 2012年07月12日 16:19
  • 8659

将链表中的节点顺序倒排序

利用三个额外的节点指针修改链表节点的指向 详细参考Reverse函数 // 倒排链表节点.cpp : Defines the entry point for the console appli...
  • zy_dreamer
  • zy_dreamer
  • 2013年06月19日 10:57
  • 1376

颠倒一个链表的顺序 C++

首先我们定义一个头结点: struct Node{ int data; Node*next; };接下来我们写一个函数来创建一个链表: //a是一个数组,n代表数组元素的个数 No...
  • wefun
  • wefun
  • 2017年11月30日 20:01
  • 23

数组元素顺序颠倒

思想是灵魂,这里我有两种思路。 1,互换位置:第一个元素与最后一个互换,第二个与倒数第二个,依次替换(定义两个变量i,j相互替换) 2,新建数组,从原数组倒序取数据存放到新数组public cla...
  • kangguowei
  • kangguowei
  • 2017年07月13日 10:06
  • 491

练习1-19 编写函数 reverse(s),将字符串s 中的字符顺序颠倒过来。使用该函数编写一个程序,每次颠倒一个输入行中的字符顺序。

练习1-19 编写函数 reverse(s),将字符串s 中的字符顺序颠倒过来。使用该函数编写一个程序,每次颠倒一个输入行中的字符顺序。自己的:思路最开始的思路是在函数里新建一个字符数组,将输入...
  • u013289703
  • u013289703
  • 2016年09月23日 17:58
  • 709
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:颠倒一个链表的顺序
举报原因:
原因补充:

(最多只允许输入30个字)