【剑指offer】递归循环两种方式反转链表

转载请注明出处:http://blog.csdn.net/ns_code/article/details/25737023


本文分别用非递归和递归两种方式实现了链表的反转,在九度OJ上AC。

题目描述:

输入一个链表,反转链表后,输出链表的所有元素。
(hint : 请务必使用链表)

输入:

输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000):代表将要输入的链表的个数。
输入的第二行包含n个整数t(0<=t<=1000000):代表链表元素。

输出:

对应每个测试案例,
以此输出链表反转后的元素,如没有元素则输出NULL。

样例输入:
5
1 2 3 4 5
0
样例输出:
5 4 3 2 1
NULL

很明显,翻转后,尾节点和头结点互换了。

我们需要设置三个指针,分别指向当前要反转的节点、当前要反转节点的前一个节点、当前要反转节点的下一个节点。要注意链表为空,以及只有一个头结点的情况。

非递归实现如下:

/*
反转链表,返回翻转后的头结点
*/
pNode ReverseList(pNode pHead)
{
	if(pHead == NULL)
		return NULL;
	if(pHead->next == NULL)
		return pHead;

	pNode pCur = pHead;
	pNode pPre = NULL;
	while(pCur != NULL)
	{
		pNode pNext = pCur->next;
		pCur->next = pPre;
		pPre = pCur;
		pCur = pNext;
	}
	return pPre;
}

递归实现如下:

/*
递归实现反转链表,返回翻转后的头结点
*/
pNode ReverseListRecursivly(pNode pPre,pNode pCur)
{
	if(pCur == NULL)
		return NULL;
	if(pCur->next == NULL)
	{
		pCur->next = pPre;
		return pCur;
	}

	pNode pNext = pCur->next;
	pCur->next = pPre;
	pNode pNewHead = ReverseListRecursivly(pCur,pNext);
	return pNewHead;
}

pNode ReverseList2(pNode pHead)
{
	return ReverseListRecursivly(NULL,pHead);
}

根据题目要求,测试代码如下:

int main()
{
	int n;
	while(scanf("%d",&n) != EOF)
	{
		pNode pHead = NULL;
		if(n > 0)
		{
			int i,data;
			scanf("%d",&data);
			pHead =(pNode)malloc(sizeof(Node));
			if(pHead == NULL)
				exit(EXIT_FAILURE);
			pHead->data = data;
			pHead->next = NULL;

			pNode pCur = pHead;
			for(i=0;i<n-1;i++)
			{
				scanf("%d",&data);
				pNode pNew =(pNode)malloc(sizeof(Node));
				if(pNew == NULL)
					exit(EXIT_FAILURE);
				pNew->data = data;
				pNew->next = NULL;
				pCur->next = pNew;
				pCur = pCur->next;
			}
		}

		pNode pNewHead = ReverseList2(pHead);
		if(pNewHead == NULL)
			printf("NULL\n");
		else
		{
			pNode pCur = pNewHead;
			while(pCur != NULL)
			{
				//这里主要时要注意输出的格式
				if(pCur->next == NULL)
					printf("%d\n",pCur->data);
				else
					printf("%d ",pCur->data);
				pCur = pCur->next;
			}
		}
	}
	return 0;
}

/**************************************************************

    Problem: 1518

    User: mmc_maodun

    Language: C

    Result: Accepted

    Time:150 ms

    Memory:2364 kb

****************************************************************/

【剑指offer】递归循环两种方式反转链表,布布扣,bubuko.com

时间: 2024-10-21 20:00:01

【剑指offer】递归循环两种方式反转链表的相关文章

剑指Offer:合并两个排序的链表【25】

剑指Offer:合并两个排序的链表[25] 题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 题目分析 每次都是比较箭头节点,把小节点连接到已经合并的链表之后,重复的执行此过程,最后如果那个链表已经走完,那就将另一个链表直接连接到合并的链表之后. Java题解 public static ListNode Merge(ListNode list1,ListNode list2) { if(list1==null) return list2;

剑指offer:合并两个排序的链表

题目描述输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. # -*- coding: utf-8 -*- # @Time : 2019-04-24 10:17 # @Author : Jayce Wong # @ProjectName : job # @FileName : mergeSortedLinkedList.py # @Blog : https://blog.51cto.com/jayce1111 # @Github : https://gi

剑指offer 16.合并两个排序的链表

16.合并两个排序的链表 题目 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 思路 这题以前也做过的,只需要新建一个表头,然后比较两边的大小,依次加入新的链表,最后再把没用上的加到结尾即可. now代表当前节点,base代表头结点. 代码 public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } public List

剑指offer和leetcode都有的_反转链表

输入一个链表,反转链表后,输出链表的所有元素. 一开始我的做法非常复杂,因为我一次变了两个指针,导致要分别判断单数个结点和偶数个结点的情况. 反转链表要解决的两个问题就是 1.结点指向它的前驱 2.头结点变为其尾结点 当反转一个结点时,假设反转i,首先需要记录它的前驱,让它指向它的前驱,还需要记录它的后继结点,否则就会造成链表的断裂,所以至少需要三个结点. 后来我整理了一下思路,发现有两种方法,一种用的是循环,一种用的是递归. 1.循环做法 /**循环做法来反转链表 * 思路是用三个指针来记录,

剑指Offer 16. 合并两个排序的链表 (链表)

题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 题目地址 https://www.nowcoder.com/practice/d8b6b4358f774294a89de2a6ac4d9337?tpId=13&tqId=11169&rp=3&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking&tPage=1 思

【剑指OFFER】合并两个排序的链表

[问题描述] 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. [AC代码] 递归版:Reference: https://blog.csdn.net/gsch_12/article/details/81156451 1 /* 2 public class ListNode { 3 int val; 4 ListNode next = null; 5 6 ListNode(int val) { 7 this.val = val; 8 } 9 }*/ 1

剑指OFFER之合并两个排序的链表

题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 解决办法 1.递归方法: if(pHead1==NULL) return pHead2; else if(pHead2==NULL) return pHead1; ListNode* pMerge=NULL; if(pHead1->val<=pHead2->val){ pMerge=pHead1; pMerge->next=Merge(pHead1->next,pHead2

剑指OFFER之用两个栈实现队列(九度OJ1512)

题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型. 输入: 每个输入文件包含一个测试样例.对于每个测试样例,第一行输入一个n(1<=n<=100000),代表队列操作的个数.接下来的n行,每行输入一个队列操作:1. PUSH X 向队列中push一个整数x(x>=0)2. POP 从队列中pop一个数. 输出: 对应每个测试案例,打印所有pop操作中从队列pop中的数字.如果执行pop操作时,队列为空,则打印-1 样例输入: 3 PUSH 10

[剑指Offer]9.用两个栈实现队列

题目 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 思路 用栈来模拟队列.我们首先插入一个元素a到stack1中,再压入两个元素bc,此时栈中有元素abc,其中c位于栈顶,而stack2仍然为空.我们试着删除一个元素.按照队列先进先出的原则,我们应该先删除元素a.元素a存放在stack1中且不在栈顶,因此不能直接删除.注意到stack2还未使用,我们把stack1中的元素逐个弹出并压入stack2中,stack2中的元素是cba,栈顶元素是a,我们现在可以