赞
踩
例题:
//1.判断单链表是否带环?若带环,求环的长度?求环的入口点?
//2.判断两个链表是否相交,若相交,求交点。(假设链表不带环)
//3.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
//4.复杂链表的复制。一个链表的每个节点,有一个指向next指针指向下一个节点,
//还有一个random指针指向这个链表中的一个随机节点或者NULL,
//现在要求实现复制这个链表,返回复制后的新链表。
////ps: 复杂链表的结构
//struct ComplexNode
//{
// int _data; // 数据
// struct ComplexNode * _next; // 指向下一个节点的指针
// struct ComplexNode * _random; // 指向随机节点(可以是链表中的任意节点 or 空)
//};
基本函数:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<math.h>
typedef int DataType;//节点中数据类型
typedef struct ListNode//节点数据结构
{
DataType data;
struct ListNode *next;
} ListNode;
ListNode *Find(ListNode *plist,DataType x)//查找函数,返回查找到节点的地址
{
ListNode *cur = plist;
while (cur)
{
if ((cur->data) == x)
{
return cur;
}
cur = cur->next;
}
return cur;
}
ListNode *BuyNode(DataType x)//产生一个节点并把节点中的数据置数,返回节点地址
{
ListNode *plist = (ListNode *)malloc(sizeof(ListNode));
if (plist != NULL)
{
plist->data = x;
plist->next = NULL;
return plist;
}
return NULL;
}
void PrintList(ListNode *plist)//打印单链表
{
assert(plist != NULL);
while (plist)
{
printf("%d->",plist->data);
plist = plist->next;
}
printf("NULL\n");
}
void PushBuck(ListNode **pplist,DataType x)//在函数尾部插入节点
{
ListNode *cur = NULL;
assert(pplist);
cur = *pplist;
if (*pplist == NULL)
{
*pplist = BuyNode(x);
return;
}
while ((cur->next) != NULL)
{
cur = cur->next;
}
cur->next = BuyNode(x);
}
思路:
ListNode *IsCycle(ListNode *plist)//判断是否带环
{
ListNode *fast = plist;
ListNode *slow = plist;
assert(plist);
while ((fast != NULL) && (fast->next != NULL))
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
return fast;
}
return NULL;
}
int GetCycleLen(ListNode *meetnode)//求环的长度
{
ListNode *cur = NULL;
int count = 1;
assert(meetnode);
cur = meetnode->next;
while (cur != meetnode)
{
cur = cur->next;
count++;
}
return count;
}
ListNode *GetCycleEnter(ListNode *plist, ListNode *meetnode)//求环的入口点
{
assert(plist);
assert(meetnode);
while (plist != meetnode)
{
plist = plist->next;
meetnode = meetnode->next;
}
return plist;
}
void Test()
{
ListNode *plist = NULL;
ListNode *tmp1 = NULL;
ListNode *tmp2 = NULL;
ListNode *tmp = NULL;
PushBuck(&plist, 1);
PushBuck(&plist, 2);
PushBuck(&plist, 3);
PushBuck(&plist, 4);
PushBuck(&plist, 5);
PushBuck(&plist, 6);
PushBuck(&plist, 7);
tmp1 = Find(plist, 3);
tmp2 = Find(plist, 7);
tmp2->next = tmp1;
tmp = IsCycle(plist);
if (tmp == NULL)
printf("不带环!\n");
else
{
printf("带环!\n");
printf("环的长度为:%d\n",GetCycleLen(tmp));
printf("环的入口点为:%d\n",GetCycleEnter(plist,tmp)->data);
}
}
结果:
bool CheckIsMeet(ListNode *plist1,ListNode *plist2)//判断是否相交
{
assert(plist1);
assert(plist2);
while (plist1->next != NULL)
{
plist1 = plist1->next;
}
while (plist2->next != NULL)
{
plist2 = plist2->next;
}
if (plist1 == plist2)
{
return true;
}
else
{
return false;
}
}
ListNode *AnswerMeetNode(ListNode *plist1,ListNode *plist2)//若相交,求交点
{
int count1 = 0;
int count2 = 0;
int count = 0;
ListNode *cur1 = plist1;
ListNode *cur2 = plist2;
while (cur1 != NULL)
{
count1++;
cur1 = cur1->next;
}
while (cur2 != NULL)
{
count2++;
cur2 = cur2->next;
}
count = count1 - count2;
if (count > 0)
{
while (count--)
{
plist1 = plist1->next;
}
}
else
{
count = -count;
while (count--)
{
plist2 = plist2->next;
}
}
while (plist1 != plist2)
{
plist1 = plist1->next;
plist2 = plist2->next;
}
return plist1;
}
void Test1()
{
ListNode *plist1 = NULL;
ListNode *plist2 = NULL;
ListNode *tmp1 = NULL;
ListNode *tmp2 = NULL;
bool flag = true;
PushBuck(&plist1, 1);
PushBuck(&plist1, 3);
PushBuck(&plist1, 5);
PushBuck(&plist1, 7);
PushBuck(&plist1, 8);
PushBuck(&plist1, 9);
PushBuck(&plist1, 10);
PushBuck(&plist2, 2);
PushBuck(&plist2, 4);
PushBuck(&plist2, 6);
tmp1 = Find(plist2, 6);
tmp2 = Find(plist1, 7);
tmp1->next = tmp2;
flag = CheckIsMeet(plist1, plist2);
if (flag)
{
printf("相交!\n");
printf("交点为:%d\n",AnswerMeetNode(plist1,plist2)->data);
}
else
{
printf("不想交!\n");
}
}
结果:
思路:
RetuenNoode CheckIsMeetTop(ListNode *plist1, ListNode *plist2)//判断两个链表是否相交,若相交,求交点.(假设链表可能带环)【升级版】
{
ListNode *tmp1 = NULL;
ListNode *tmp2 = NULL;
RetuenNoode ret = { 0, NULL, NULL };
assert(plist1);
assert(plist2);
tmp1 = IsCycle(plist1);
tmp2 = IsCycle(plist2);
if ((tmp1 == NULL) && (tmp2 == NULL))
{
//都不带环
tmp1 = plist1;
tmp2 = plist2;
while (tmp1->next != NULL)
{
tmp1 = tmp1->next;
}
while (tmp2->next != NULL)
{
tmp2 = tmp2->next;
}
if (tmp1 == tmp2)
{
//相交
ret.plist1 = AnswerMeetNode(plist1, plist2);
ret.flag = 1;
return ret;
}
else
{
//不相交
ret.flag = 1;
return ret;
}
}
else if ((tmp1 != NULL) && (tmp2 != NULL))
{
//两者都带环
ListNode *tmp = tmp1->next;
while ((tmp != tmp2) && (tmp != tmp1))
{
tmp = tmp->next;
}
if (tmp == tmp2)
{
//相交
tmp1 = GetCycleEnter(plist1,tmp1);
tmp2 = GetCycleEnter(plist2,tmp2);
if (tmp1 == tmp2)
{
//交点在链上
int count1 = 0;
int count2 = 0;
int count = 0;
ListNode *cur1 = plist1;
ListNode *cur2 = plist2;
while (cur1 != tmp1)
{
count1++;
cur1 = cur1->next;
}
while (cur2 != tmp1)
{
count2++;
cur2 = cur2->next;
}
count = count1 - count2;
if (count > 0)
{
while (count--)
{
plist1 = plist1->next;
}
}
else
{
count = -count;
while (count--)
{
plist2 = plist2->next;
}
}
while (plist1 != plist2)
{
plist1 = plist1->next;
plist2 = plist2->next;
}
ret.plist1 = plist1;
ret.flag = 3;
return ret;
}
else
{
//两个交点都在环上
ret.plist1 = tmp1;
ret.plist2 = tmp2;
ret.flag = 3;
return ret;
}
}
else
{
//不相交
ret.flag = 3;
return ret;
}
}
else
{
//一个带环,一个不带环。必不相交
ret.flag = 2;
return ret;
}
}
void Test2()
{
RetuenNoode ret = {0,NULL,NULL};
ListNode *plist1 = NULL;
ListNode *plist2 = NULL;
ListNode *tmp1 = NULL;
ListNode *tmp2 = NULL;
PushBuck(&plist1, 1);
PushBuck(&plist1, 3);
PushBuck(&plist1, 5);
PushBuck(&plist1, 7);
PushBuck(&plist1, 8);
PushBuck(&plist1, 9);
PushBuck(&plist1, 10);
PushBuck(&plist2, 0);
PushBuck(&plist2, 2);
PushBuck(&plist2, 4);
PushBuck(&plist2, 6);
tmp1 = Find(plist1, 10);//第三类相交 b> 2>
tmp2 = Find(plist1, 7);
tmp1->next = tmp2;
tmp1 = Find(plist1, 9);
tmp2 = Find(plist2, 6);
tmp2->next = tmp1;
//tmp1 = Find(plist1, 10);//第三类相交 b> 1>
//tmp2 = Find(plist1, 7);
//tmp1->next = tmp2;
//tmp1 = Find(plist1, 5);
//tmp2 = Find(plist2, 6);
//tmp2->next = tmp1;
//tmp1 = Find(plist2, 2);//第三类不相交
//tmp2 = Find(plist2, 6);
//tmp2->next = tmp1;
//tmp1 = Find(plist1, 7);
//tmp2 = Find(plist1, 10);
//tmp2->next = tmp1;
//tmp1 = Find(plist1, 7);//第二类不相交
//tmp2 = Find(plist1, 10);
//tmp2->next = tmp1;
//第一类不相交
//tmp1 = Find(plist2, 6);//第一类相交
//tmp2 = Find(plist1, 7);
//tmp1->next = tmp2;
ret = CheckIsMeetTop(plist1,plist2);
if (ret.flag == 3)
{
if ((ret.plist1) && (ret.plist2))
{
printf(" 第三类 -> b> -> 2> :\nMeetNode1:%d\nMeetNode2:%d\n", ret.plist1->data, ret.plist2->data);
}
else if (ret.plist1)
{
printf("第三类 -> b> -> 1> :\nMeetNode:%d\n", ret.plist1->data);
}
else
{
printf("第三类不相交!\n");
}
}
else if (ret.flag == 1)
{
if (ret.plist1)
{
printf("第一类相交:\nMeetNode:%d\n", ret.plist1->data);
}
else
{
printf("第一类不相交!\n");
}
}
else
{
printf("第二类不相交!\n");
}
}
int main()
{
//Test();
//Test1();
Test2();
return 0;
}
结果:
思路:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int DataType;
typedef struct ComplexNode
{
DataType data;//数据
struct ComplexNode *next;//指向下一个节点
struct ComplexNode *random;//指向随机节点
} ComplexNode;
ComplexNode *BuyNode(DataType x)//产生新节点
{
ComplexNode *tmp = (ComplexNode *)malloc(sizeof(ComplexNode));
tmp->data = x;
tmp->next = NULL;
tmp->random = NULL;
return tmp;
}
void PushBack(ComplexNode **pplist,DataType x)//尾插函数
{
ComplexNode *cur = NULL;
assert(pplist);
cur = *pplist;
if (*pplist == NULL)
{
*pplist = BuyNode(x);
}
else
{
while (cur->next)
{
cur = cur->next;
}
cur->next = BuyNode(x);
}
}
ComplexNode *FindComplexNode(ComplexNode *plist,DataType x)//查找函数
{
if (plist == NULL)
{
return NULL;
}
else
{
while (plist)
{
if (plist->data == x)
return plist;
plist = plist->next;
}
return NULL;
}
}
ComplexNode *LineComplexNode(ComplexNode *plist)//第一步、产生节点并连接节点
{
ComplexNode *phead = plist;
ComplexNode *tmp = NULL;
ComplexNode *ret = NULL;
assert(plist);
while (plist)
{
ret = plist->next;
tmp = BuyNode(plist->data);
tmp->next = plist->next;
plist->next = tmp;
tmp->random = NULL;
plist = ret;
}
return phead;
}
void RandomEvaluate(ComplexNode *plist)//第二步、random指针赋值
{
assert(plist);
while (plist)
{
if (plist->random == NULL)
{
plist->next->random = NULL;
}
else
{
plist->next->random = plist->random->next;
}
plist = plist->next->next;
}
}
void PrintComplexNode(ComplexNode *plist)//打印节点
{
while (plist)
{
printf("%d->",plist->data);
plist = plist->next;
}
printf("NULL\n");
}
void PrintRandom(ComplexNode *plist)//打印random指向的数据
{
while (plist)
{
if (plist->random == NULL)
{
printf("NULL->");
}
else
{
printf("%d->", plist->random->data);
}
plist = plist->next;
}
printf("STOP\n");
}
ComplexNode *ToPickComplexList(ComplexNode *plist)//摘出复杂链表
{
ComplexNode *phead = NULL;
ComplexNode *cur = NULL;
ComplexNode *tmp = NULL;
if (plist == NULL)
{
return NULL;
}
while (plist)
{
cur = plist->next;
plist->next = cur->next;
if (phead == NULL)
phead = tmp = cur;
else
{
tmp->next = cur;
tmp = cur;
}
plist = plist->next;
}
return phead;
}
void Test()
{
ComplexNode *plist = NULL;
ComplexNode *tmp1 = NULL;
ComplexNode *tmp2 = NULL;
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PushBack(&plist, 4);
PushBack(&plist, 5);
tmp1 = FindComplexNode(plist, 3);
plist->random = tmp1;
tmp1->random = NULL;
tmp1 = FindComplexNode(plist, 2);
tmp1->random = plist;
tmp1 = FindComplexNode(plist, 4);
tmp2 = FindComplexNode(plist, 5);
tmp1->random = tmp2;
tmp2->random = tmp2;//初始化复杂链表
LineComplexNode(plist);//第一步
RandomEvaluate(plist);//第二步
tmp1 = ToPickComplexList(plist);//摘出链表
PrintComplexNode(plist);//打印原始链表
PrintRandom(plist);//打印原始Random所指向数据
PrintComplexNode(tmp1);//打印新链表
PrintRandom(tmp1);//打印新random所指向数据
}
int main()
{
Test();
return 0;
}
结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。