链表逆置相关算法题|原地逆置|轮转链表|循环链表逆置(C)

原地逆置

试编写算法将带头结点的单链表就地逆置,所谓"就地"是指辅助空间复杂度为O(1)。

思路1

将头节点摘下,然后从第一节点开始,依次插入到头节点后面,头插法建立单链表,直到最后一个节点为止

断开L和链表

将cur的next指向L的next

将L的next指向cur

完成插入,将cur指向next,next指向cur的next

LinkList ReverseL(LinkList &L)
{
	LNode* cur, *next;
	cur = L->next;
	L->next = NULL;
	while (cur)
	{
		next = cur->next;
		cur->next = L->next;
		L->next = cur;
		cur = next;
	}
	return L;
}

一个工作指针cur用来遍历链表,一个后继指针next用来保存cur的下一个节点

cur指向第一个节点,将哨兵位的next置为NULL,与后面的链表断开链接

cur往后遍历,直到cur指向NULL

将next指向cur的next,保存下一个节点

将cur的next指向哨兵位的next,将cur节点插入到哨兵节点之后

将L的next指向cur,将哨兵节点和当前节点进行链接

将cur指向next,继续往后遍历

最后返回链表L

思路2

用三个指针prev,cur,next来表示三个连续的节点

处理第一个节点,cur的next指向NULL

prev指向cur,cur指向next,next指向next的next

cur的next指向prev

直到next指向NULL

最后将L的next指向cur节点,也就是原来的尾节点

完成逆置

LinkList ReverseL(LinkList &L)
{
	LNode* prev, *cur = L->next, *next = cur->next;
	cur->next = NULL;
	while (next)
	{
		prev = cur;
		cur = next;
		next = next->next;
		cur->next = prev;
	}
	L->next = cur;
	return L;
}

一个工作指针cur用来遍历链表,一个后继指针用来保存cur的下一个节点,一个前驱指针prev用来保存前一个节点

cur指向L的next,从第一个节点开始

将当前遍历的节点的next指向NULL

开始遍历:

将prev指向cur,cur指向next,next指向next的下一个,三个指针往后走一步

将cur的next指向perv,将中间节点的next指向前一个节点

直到第三个节点指向NULL,也就是最后一个节点的next指向倒数第二个节点

最后将L的next指向cur,也就是哨兵位头节点指向最后一个节点,完成逆置

返回链表L

轮转链表

设将n ( n > 1 ) (n>1) (n>1)个整数存放到不带头结点的单链表L中,将L中保存的序列循环右移k ( 0 < k < n ) (0<k<n) (0<k<n)个位置。例如,若k=1,则将链表{0,1,2,3}变为{3,0,1,2}。

算法思想

首先,遍历链表计算表长n,并找到链表的尾节点,将其与头节点相连,构成一个循环单链表

然后找到新链表的尾节点,为原链表的第n-k个节点,令L指向新链表尾节点的下一个节点,并将环断开,得到新链表

LinkList* Converse(LinkList &L, int k)
{
	int n = 1;
	LNode* cur = L;
	while (cur->next)
	{
		cur = cur->next;
		n++;
	}
	cur->next = L;
	for (int i = 1; i <= n - k; i++)
	{
		cur = cur->next;
	}
	L = cur->next;
	cur->next = NULL;
	return L;
}

将n初始化为1,cur指向L,cur的next指向第一个节点,往后遍历直到cur的next指向NULL,cur指向最后一个节点

再下一次cur->next指向NULL,不进入循环

这样遍历出链表的节点个数

将cur的next指向L

构成循环链表

若k=1,也就是要右移一个位置

新链表的尾节点也就是第n-k个节点,也就是第4-1=3个节点

从头遍历依次,找到第n-k个节点,用cur指针指向

令L指向新链表尾节点的下一个节点

将cur的next指向NULL,断开环

完成右移

循环链表逆置

与逆置单链表的不同之处:

  1. 初始化成循环链表而不是空链表

  2. 判断链表尾不用空指针而用是否是链表头指针

    void reverse(LinkList &L)
    {
    LNode* cur = L->next, *next;
    L->next = L; //初始化成空循环链表

     while (cur != L)       //当cur等于L时结束
     {
     	next = cur->next;  //暂存cur的后继节点
     	cur->next = L->next;
     	L->next = cur;
     	cur = next;
     }
     return L;
    

    }

让L的next指向自己,循环链表的初始化

用next指针指向cur的下一个节点

将cur的next指向L的next

L的next指向cur

cur指向next

直到cur指向L

完成逆置

相关推荐
代码小将7 分钟前
PTA数据结构编程题7-1最大子列和问题
数据结构·c++·笔记·学习·算法
yangjiwei020743 分钟前
数据结构-排序
数据结构·python
坊钰1 小时前
【Java 数据结构】合并两个有序链表
java·开发语言·数据结构·学习·链表
抓住鼹鼠不撒手1 小时前
力扣 429 场周赛-前两题
数据结构·算法·leetcode
南宫生2 小时前
力扣-数据结构-3【算法学习day.74】
java·数据结构·学习·算法·leetcode
向宇it2 小时前
【从零开始入门unity游戏开发之——C#篇30】C#常用泛型数据结构类——list<T>列表、`List<T>` 和数组 (`T[]`) 的选择
java·开发语言·数据结构·unity·c#·游戏引擎·list
A懿轩A2 小时前
C/C++ 数据结构与算法【树和二叉树】 树和二叉树,二叉树先中后序遍历详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·二叉树·
DogDaoDao4 小时前
leetcode 面试经典 150 题:矩阵置零
数据结构·c++·leetcode·面试·矩阵·二维数组·矩阵置零
徐子童5 小时前
二分查找算法专题
数据结构·算法
小王子10245 小时前
数据结构与算法Python版 二叉查找树
数据结构·python·算法·二叉查找树