带头结点的尾指针表示的循环链表的合并
为什么要用带尾指针的而不是用带头指针的呢?
如下图:
因为带尾指针的话找头结点方便啊(时间复杂度O(1)),但是带头指针的找尾结点不方便啊(需要遍历,时间复杂度O(n))
循环链表与单链表相比要注意的点
注意:循环链表的空链表的表示为头结点的指针指向自己(即存头结点的自己地址)
如何终止:原来是p/p->next是否为空,现在是判断它们是否等于头指针
两个循环链表的合并
注意:按照上述合并之后,尾指针现在变为Tb了。
#include <iostream>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXSIZE 100
using namespace std;
typedef int Status;//返回值类型
typedef char ElemType;//数据类型
using namespace std;
typedef struct Lnode{
ElemType data;
Lnode* next;
}Lnode,*LinkList;
//初始化一个空的链表
Status initList(LinkList &L){
//Lnode L=new Lnode;//c++语法用delete销毁,c的语法为;用free销毁
L=(LinkList)malloc(sizeof(Lnode));
L->next=L;
return OK;
}
//合并两个链表成为循环链表,现在两个链表都为循环链表la,lb为尾指针
void mergeLink(LinkList &la,LinkList &lb){
Lnode* p=la->next;
la->next=lb->next->next;
free(lb->next);
lb->next=p;
//此时lb指向尾节点
}
//创建循环链表
void create(LinkList &L,int n){
initList(L);
while(n>0){
Lnode* p=new Lnode;
cin>>p->data;
p->next=L->next;
L->next=p;
L=p;
n--;
}
}
//遍历一个链表
void select(LinkList L){
Lnode* p;
p=L->next->next;
while(p!=L->next){
printf("数据为:%c\n",p->data);
p=p->next;
}
}
int main()
{
LinkList la,lb;
create(la,5);
select(la);
create(lb,5);
select(lb);
printf("合并后:\n");
mergeLink(la,lb);
select(lb);//为什么这里是lb呢,上面讲过喔,就是合并完的尾指针是lb,你也可以修改一下上面mergeLink函数,使它返回尾指针也可以
return 0;
}
这样合并的时间复杂度是O(1)