欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)

链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)

2025/4/19 14:40:13 来源:https://blog.csdn.net/CoderZzz6310/article/details/143687289  浏览:    关键词:链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)

判断循环双链表是否对称

设计一个算法用于判断带头节点的循环双链表是否对称

算法思想

让left从左向右扫描,right从右向左扫描,直到它们指向同一个节点:left == right
或相邻left->next == right,或right->prev == left,为止
若它们所指节点值相同,则继续下去,否则返回false,若比较全部相等,则返回true
![[Pasted image 20241111143209.png]]

当节点个数是奇数
![[Pasted image 20241111143238.png]]

直到left == right时,循环结束
![[Pasted image 20241111143329.png]]

当节点个数是偶数
![[Pasted image 20241111143359.png]]

直到发生交错后,right的next指向left,循环结束

bool Symmetry(DLinkList &L)
{// 初始化左右指针,指向链表的首尾节点DNode* left = L->next, *right = L->prev;// 当左右指针未相遇,且未交错while (left != right && right->next != left){// 如果左右数据相等if (left->data == right->data){// 左指针右移left = left->next;// 右指针左移right = right->prev;}// 如果不相等,则链表不对称elsereturn false;}// 循环结束,说明链表对称return true;
}

两循环单链表合并成循环链表

有两个循环单链表,链表头指针分别为h1和h2,编写一个函数将链表h2链接到链表h1之后,要求连接后的链表仍保持循环链表的形式

算法思想

先找到两个链表的尾指针,将第一个链表的尾指针与第二个链表的头指针链接起来,再使之成为循环链表
![[Pasted image 20241111144227.png]]

找尾
![[Pasted image 20241111144245.png]]

将cur1的next指向h2
![[Pasted image 20241111144324.png]]

将cur2的next指向h1
![[Pasted image 20241111144347.png]]

构成循环链表

LinkList Link(LinkList &h1, LinkList &h2)
{// 创建两个工作指针cur1和cur2LNode* cur1, cur2;cur1 = h1;// 寻找h1的尾节点while (cur1->next != h1){cur1 = cur1->next;}cur2 = h2;// 寻找h2的尾节点while (cur2->next != h2){cur2 = cur2->next;}// 将h2链接到h1之后cur1->next = h2;// 令h2的尾节点指向h2cur2->next = h1;return h1;
}

使双向循环链表有序

已知一双向循环链表,从第二个节点至表尾递增有序
将第一个节点删除并插入表中适当位置,使整个链表递增有序

算法思想

应该先将第一节点从链表上摘下来,再将其插入到链表中相应的位置,由于是双向链表,不必像单链表那样插入节点的前驱
![[Pasted image 20241111145739.png]]

断开tmp和链表
cur的prev指向L的prev
![[Pasted image 20241111145942.png]]

L的prev的next指向cur
![[Pasted image 20241111150019.png]]

查插入位置
直到cur的data大于等于x后停下,之后把原第一个节点插在cur的前一个位置
tmp的next指向cur,tmp的prev指向cur的prev
![[Pasted image 20241111150227.png]]

cur的前一个的next指向tmp,cur的prev指向tmp
![[Pasted image 20241111150320.png]]

void DInsert(DLinkList &L)
{// tmp暂存第一节点的指针DNode* tmp = L;int x = L->data;// 将第一个节点从链表上摘下DNode* cur = L->next;cur->prev = L->prev;L->prev->next = cur;// 查插入位置while (cur && cur->data < x){cur = cur->next;}// 插入原第一节点tmp->next = cur;tmp->prev = cur->prev;cur->prev->next = tmp;cur->prev = tmp;
}

单循环链表改双向循环链表

假设一个单循环链表,其节点含有三个域,prev,data,next,prev为空指针,next指向后继节点
将此表改为双向循环链表
![[Pasted image 20241111153358.png]]

cur的next的prev指向cur
直到cur的next的prev不为空
![[Pasted image 20241111153514.png]]

cur正好遍历完链表

算法思想

关键是控制每个节点均置上指向前驱的指针,而且每个节点的前驱指针置且仅置一次

void StoDouble(LinkList &L)
{LNode* cur = L;while (cur->next->prev == NULL){cur->next->prev = cur;cur = cur->next;}
}

两链表的差集

已知递增有序的单链表A,B分别存储了一个集合,请设计算法以求出两个集合A和B的差集,A-B,并以同样的方式存储,同时返回该集合的元素个数

算法思想

在A中删除A和B中共有的元素,由于是单链表,删除节点要记住被删除节点的前驱,两个链表都开始遍历,直到一个链表遍历结束

void Difference(LinkList &A, LinkList &B, int* n)
{// cura和curb分别是链表A和B的工作指针LNode* cura = A->next;LNode* curb = B->next;// prev为链表A中cur所指节点的前一个节点LNode* prev = A;while (cura && curb){if (cura->data < curb->data){prev = cura;cura = cura->next;*n++;}else if (cura->data > curb->data){curb = curb->next;}// 元素值相同的节点,删除else{prev->next = cura->next;LNode* del = cura;cura = cura->next;free(del);}}while (cura){cura = cura->next;*n++;}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词