循环链表和双向链表<C语言版>

循环链表

定义

  循环链表是一种头尾相接的链式存储结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。

  循环链表的优点是从表中任意结点出发都可以找到表中其他结点。由于表的操作往往是在表的首尾进行的,当头指针表示单链表循环时,找结点1和结点n的时间复杂度分别为O(1)和O(n);当尾指针表示单链表循环时,找结点1和结点n的时间复杂度都为O(1),故通常用尾指针。

结点定义如下:

​
typedef struct LinkList{
	int data;
LinkList* next;
}LNode,*LinkNode;

​

初始化

  循环链表只需让组后一个结点的指针域指向头结点,以单链表为例,只需在初始化时将最后结点的指针指向头结点。

void InitLink (LinkNode & L){
	L = (LinkNode)malloc(sizeof(LNode));
	L->next = L;
	return;
}

  但由于循环链表中没有NULL指针,故涉及遍历操作时,其终止条件变为判断指针是否等于头结点,以验空为例。

void CheckLinkEmpty(LinkNode L) {
	if (L == NULL) { printf("No exist\n"); }
	else if (L->next == L) { printf("Empty!\n"); }
	else { printf("No empty!\n"); }
	return;
}

循环链表合并

将两个带头结点的循环单链表ListA和ListB合并为一个带头结点的循环单链表ListC。第一步储存ListA,ListB的头结点,第二步将两个表的结点移至尾结点,第三步将A的尾结点连到B的首结点,将B的尾结点连到A的头结点,第四步释放B的头结点,第五步,返回A的头结点。

LinkNode ConnectLinkList(LinkNode &ListA, LinkNode &ListB) {
	LNode* q = ListA;
	LNode* p = ListB;
	LNode* m = (LinkNode)malloc(sizeof(LNode));
	while (ListA->next!=q)
	{
		ListA = ListA->next;
	}
	while (ListB->next != p)
	{
		ListB = ListB->next;
	}
	m = ListA->next;
	ListA->next = ListB->next->next;
	free(p);
	ListB->next = m;
	ListA = q;
	return ListA;
}

测试:输入A{8,7,6,5,9},B{1,2,3,4},输出链表C的1~9位,结果如下:

双向链表

定义

  双向链表是在单向链表基础上的一个改进,每个节点指向其直接前驱和直接后继节点。对于双向链表来说,它的每个节点要指向“直接前驱”和“直接后继”,所以节点类需要含有两个指针域。指向直接前驱的指针使用pre表示,指向后继的指针使用next表示。双向链表的优点是:从双向链表的任意位置开始,都能访问所有的节点。双向链表定义如下:

typedef struct DuLinkList {
	DuLinkList* pre;
	int data;
	DuLinkList* next;
}DuNode, * DuLinkNode;

相关操作

初始化

  双向链表不仅需让头结点next指针域指向NULL,还需要让头结点pre指针指向NULL。

typedef struct DuLinkList {
	DuLinkList* pre;
	int data;
	DuLinkList* next;
}DuNode, * DuLinkNode;

插入

双向链表的插入操作更加复杂,需要改变pre指针。双向链表的插入操作时间复杂度为O(n)。

void DuAddLink(DuLinkNode& L, int r, int e) {
	DuNode* p = L;
	DuNode* q = (DuLinkNode)malloc(sizeof(DuNode));
	q->data = e;
	for (int i = 1; i < r; i++) {
		p = p->next;
	}
	q->next = p->next;
	q->pre=p;
	p->next = q;
	q->next->pre = q;
	return;
}

删除

双向链表的删除操作时间复杂度也为O(n)。

void DuDeleteLink(DuLinkNode& L, int r) {
	DuNode* p = L;
	DuNode* q = (DuLinkNode)malloc(sizeof(DuNode));
	for (int i = 1; i < r; i++) {
		p = p->next;
	}
	q->next = p->next;
	q->pre = p->next->pre;
	p->next = p->next->next;
	p->next->pre = p;
	free(q);
	return;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值