颠倒一个链表的顺序

原创 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.

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

相关文章推荐

只遍历一次,将单链表中的元素顺序反转过来

转载请注明出处。 思想很简单,边遍历边将指针反向,顺便将数据往前移一个单位,这样原来的最后一个节点就变成头节点了。 代码实现如下: #include #include typedef struc...

单链表倒置(顺序与递归)

单链表倒置,给你一个头指针,用递归与非递归的方法分别实现; 分析见代码; 代码如下: // [9/30/2013 qingezha] 链表倒置 循环与递归形式 // 一般形式,1—>2->...
  • qingen1
  • qingen1
  • 2013年10月10日 10:49
  • 1301

颠倒链接表顺序

用一种算法来颠倒一个单链表的顺序,递归和非递归 #include using namespace std; struct Node { int data; Node *next; }; N...

算法与数据结构面试题(10)-颠倒链表

题目 用一种算法来颠倒一个链接表的顺序。现在在不用递归式的情况下做一遍。 解题思路 1.先用递归颠倒 2.尝试不用递归颠倒 代码 1.递归式 ...

C++算法之 倒序输出一个链表

题目:给定一个头结点,倒叙输出一个链表   解法1:先将链表反转,在遍历输出 解法2:不修改链表自身的结构,动态申请一段空间,申请一个指针数组,数组内存放的指针指向链表的每个值,再遍历数组输出:...

给定一个单向链表(长度未知),请设计一个既节省时间又节省空间的算法来找出该链表中的倒数第m个元素。实现这个算法,并为可能出现的特例情况安排好处理措施。“倒数第m个元素”是这样规定的:当m=0时,链表的

给定一个单向链表(长度未知),请设计一个既节省时间又节省空间的算法来找出该链表中的倒数第m个元素。实现这个算法,并为可能出现的特例情况安排好处理措施。“倒数第m个元素”是这样规定的:当m=0时,链表的...

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

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

单链表-----单链表的倒置

【例2-4】已知单链表H,写一算法将其倒置,即实现如图2.14所示的操作,其中(a)为倒置前,(b)为倒置后。 数据结构(C#语言版) 2.3 单链表 57 H 40 60 80 45 23 11 ∧...

单链表倒置算法

先上代码。 void reverse(list *head) { list *p, *tmp; p = head->next;  //p指向当前正在处理的节点 ...

怎样把一个链表掉个顺序

#include #include struct node { int num; node *next; }; void creatnode(node *&p,int a[],int n,int...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:颠倒一个链表的顺序
举报原因:
原因补充:

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