单链表就地逆置的两种方法(递归与普通循环)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单链表就地逆置的两种方法(递归与普通循环)相关的知识,希望对你有一定的参考价值。

参考技术A 一、用递归算法

对于不带头结点的单链表(a1,a2,a3,a4,a5,a6)逆置后的结果为(a6,a5,a4,a3,a2,a1)

考虑递归算法,若只有一个结点,则直接返回,若存在两个结点(a1,a2)则需要做的操作有:

 a2->next=a1;a1->next=NULL;return a2;

a2即新的头结点,若有三个结点,则应先将子链(a2,a3)先逆置且返回该子链的新的头结点,然后把子链(a2,a3)当作一个复合结点a2',组成新的二元组(a1,a2')然后就可以执行前面相同的操作:a2'->next=a1;a1->next=NULL;return a3'; 即可,多个以上的结点可同理得到,

Node *Reverse(Node *head)



 Node *p=head;

 if(p==NULL)

  return NULL;     //若是空链表,返回空

 Node *q=p->next;

 if(q==NULL)

  return p;     //若只有一个结点,直接返回

 else

 head=Reverse(q);  //记录子序列的新的头结点

 q->next=p;     //当前结点与已经逆置的子序列看成是前后的两个结点p,q,作相应的逆置操作

 p->next=NULL;

 return head;      //返回新的子序列的头结点



二、用普通算法循环逆置(头插法重新建立带头结点的新链表)

参考链接:https://blog.csdn.net/onlyoncelove/article/details/81988514

试用顺序表作为存储结构,实现将线性表(a0,a1,...an-1)就地逆置的操作,所谓"就地"指辅助空间应为O(1)。

请各位高手尽快给一个答案啊,帮帮忙啊

参考技术A 2楼的答案完全是照着1楼的写的,但是又不如1楼的好;
1楼的用一个变量,2楼用了两个变量。
参考技术B 算法思想是直接交换原先位置上的元素和逆置后位于该位置上的元素,则原先位于size-i位置上的元素逆置后会正好在i位置(i = 0, 1, ..., size/2), 依次交换这些元素即可。交换时使用的异或操作,可以不用中间变量来完成交换。

void reverse(int a[], int size)

for(int i = 0; i < size/2; i++)

a[i] = a[i] ^ a[size-i];
a[size-i] = a[i] ^ a[size-1];
a[i] = a[i] ^ a[size-1];

以上是关于单链表就地逆置的两种方法(递归与普通循环)的主要内容,如果未能解决你的问题,请参考以下文章

单链表的逆置使用递归算法出现-842150451这个值,请求高手予以解决。。

如何用c语言实现单链表的逆置?

字符串逆置的两种递归写法

单链表逆置

C++程序设计 编写程序实现单链表逆置功能。

求不带头结点的单链表的逆置算法?