【算法题】使用递归和非递归实现单向链表的转置

在阅读的过程中有任何问题,欢迎一起交流

邮箱:[email protected]

QQ:1494713801

问题:

给一个单向链表,把它从头到尾反转过来。比如: a -> b -> c ->d 反过来就是 d -> c -> b -> a 。

分析:

假设每一个node的结构是:

class Node { char value; Node next;}

非递归方式代码如下:

1. void reverse(struct Node **list)

2. {

3.     struct Node *currentp = *list;

4.     struct Node *pleft = NULL;

5.     struct Node *pright = NULL;

6.

7.

8.     while (currentp != NULL) {

9.         pright = currentp->next;

10.         currentp->next = pleft;

11.         pleft = currentp;

12.         currentp = pright;

13.     }

14.     *list = pleft;

15. }

递归的方式代码如下:

1. struct Node* recursive_reverse(struct Node *list)

2. {

3.     struct Node *head = list;

4.     struct Node *p = r_reverse(list);

5.     head->next = NULL;

6.     return p;

7. }

8.

9. struct Node *r_reverse(struct Node *list)

10. {

11.     if (NULL == list || NULL == list->next)

12.         return list;

13.     struct Node *p = r_reverse(list->next);

14.     list->next->next = list;

15.     return p;

16. }

递归的方法其实是非常巧的,它利用递归走到链表的末端,然后再更新每一个node的next 值 (代码倒数第二句)。 在上面的代码中, reverseRest 的值没有改变,为该链表的最后一个node,所以,反转后,我们可以得到新链表的head。

单链表相邻元素转置(非递归)

1. struct Node* recursive_reverse(struct Node *list)

2. {

3.     struct Node *head = list;

4.     struct Node *p = r_reverse(list);

5.     head->next = NULL;

6.     return p;

7. }

8.

9. struct Node *r_reverse(struct Node *list)

10. {

11.     if (NULL == list || NULL == list->next)

12.         return list;

13.     struct Node *p = r_reverse(list->next);

14.     list->next->next = list;

15.     return p;

16. }

4   单链表相邻元素转置(递归)

1. struct Node * recursive_partial_reverse(struct Node *list)

2. {

3.     if (NULL == list || NULL == list->next)

4.         return list;

5.     struct Node *p = list->next;

6.     struct Node *node = recursive_partial_reverse(list->next->next);

7.     list->next->next = list;

8.     list->next = node;

9.     return p;

10. }

参考链接:

http://blog.csdn.net/skylinesky/article/details/760694

时间: 2025-01-14 12:38:15

【算法题】使用递归和非递归实现单向链表的转置的相关文章

每天刷个算法题20160521:二叉树高度(递归与非递归)

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51502727 为了防止思维僵化,每天刷个算法题.已经刷了几天了,现在发点代码. 我已经建了一个开源项目,每天的题目都在里面: https://github.com/Xiaofei-it/Algorithms 绝大部分算法都是我自己写的,没有参考网上通用代码.读者可能会觉得有的代码晦涩难懂,因为那是我自己的理解. 最近几天都是在写一些原来的东西

每天刷个算法题20160524:阿克曼函数的递归转非递归解法

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51524754 为了防止思维僵化,每天刷个算法题.已经刷了几天了,现在发点代码. 我已经建了一个开源项目,每天的题目都在里面: https://github.com/Xiaofei-it/Algorithms 绝大部分算法都是我自己写的,没有参考网上通用代码.读者可能会觉得有的代码晦涩难懂,因为那是我自己的理解. 最近几天都是在写一些原来的东西

每天刷个算法题20160523:骑士巡游的递归转非递归解法

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51524728 为了防止思维僵化,每天刷个算法题.已经刷了几天了,现在发点代码. 我已经建了一个开源项目,每天的题目都在里面: https://github.com/Xiaofei-it/Algorithms 绝大部分算法都是我自己写的,没有参考网上通用代码.读者可能会觉得有的代码晦涩难懂,因为那是我自己的理解. 最近几天都是在写一些原来的东西

每天刷个算法题20160525:快速排序的递归转非递归解法

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51524798 为了防止思维僵化,每天刷个算法题.已经刷了几天了,现在发点代码. 我已经建了一个开源项目,每天的题目都在里面: https://github.com/Xiaofei-it/Algorithms 绝大部分算法都是我自己写的,没有参考网上通用代码.读者可能会觉得有的代码晦涩难懂,因为那是我自己的理解. 最近几天都是在写一些原来的东西

8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来探讨一下非递归方案 实验结果令人还是有些失望,原来非递归方案的性能并不比递归方案性能高 代码如下: package com.newflypig.eightqueen; import java.util.Date; /** * 使用循环控制来实现回溯,解决N皇后 * @author [email pr

二叉树遍历算法总结(递归与非递归)

一:前言 二叉树的遍历方法分四种:前序,中序,后序以及层次遍历. 其中,前中后遍历方法的实现分递归和非递归,非递归遍历的实现需要借助于栈. 实际上,递归的调用就是一种栈的实现,所以,非递归遍历就需要人工借助栈结构来实现. 而层次遍历需要借助队列. 二:前中后序遍历 递归遍历: 递归遍历的思想和方法很简单,通过调整输出语句来实现前,中,后三种遍历. 代码如下: 1 void show(BiTree T) 2 { 3 if(T) 4 { 5 printf("%c ",T->data)

算法学习 - 递归与非递归,位运算与乘除法速度比较

递归调用非递归调用 运行时间比较 结论 位运算与乘除法 结论 递归调用/非递归调用 我们都知道,很多算法,都是用递归实现的.当然它们同时也是可以用非递归来实现. 一般我们在对二叉树进行遍历的时候,还有求斐波那契数的时候,递归是非常简单的.代码容易懂,好实现. 但是递归的时候,有一个问题,就是需要压栈.为什么要压栈呢?因为当我在函数内部调用自身的时候,要中断当前的操作继续跳转到下一次的实现,而当前运行的状态要保存起来.所以就把当前状态进行压栈,等到运行到递归条件结束的时候,再弹栈. 所以递归就是需

算法:归并算法的递归与非递归形式

归并算法是将两个或两个以上的有序表组合成一个新的有序表,它的原理是:假设初始序列含有n个记录,则可以看成是n个有序子序列,两两归并,得到[n/2]个有序子序列,再次归并--不断重复直至归并到长度为n的有序序列,这样的排序方法称为2路归并排序. 实例一:递归形式的2路归并算法 #define MAXSIZE 4 int data[MAXSIZE] = {2,1,0,3}; /* * 功能:将from数组min到max-1下标数据排好序,最后的结果是to[min]...to[max-1] * 输入:

二叉树递归与非递归遍历,最近公共父节点算法

#include <iostream> #include <stack> using namespace std; #define MAX 100 //字符串最大长度 typedef struct Node //二叉树结点 { char data; Node *lchild,*rchild; } *Btree; void createBT(Btree &t); //先序构造二叉树 void preorder(Btree &t); //二叉树递归先序遍历 void i

二分查找算法(递归与非递归两种方式)

首先说说二分查找法. 二分查找法是对一组有序的数字中进行查找,传递相应的数据,进行比较查找到与原数据相同的数据,查找到了返回1,失败返回对应的数组下标. 采用非递归方式完成二分查找法.java代码如下所示. /* * 非递归二分查找算法 * 参数:整型数组,需要比较的数. */ public static int binarySearch(Integer[]srcArray,int des){ //第一个位置. int low=0; //最高位置.数组长度-1,因为下标是从0开始的. int h