带头双向循环链表

#pragma once
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
typedef int DataType;
typedef struct DNode
{
	DataType data;
	struct DNode *next;
	struct DNode *prev;
}DNode;
DNode *CreateDNode(int data)
{
	DNode *node = (DNode*)malloc(sizeof(DNode));
	node->data = data;
	node->prev = node->next = NULL;
	return node;
}
void DNodeInit(DNode **ppHead)
{
	assert(ppHead != NULL);
	DNode *node = CreateDNode(0);
	node->next = node;
	node->prev = node;
	*ppHead = node;
}
void DNodePushFront(DNode *head,DataType data)
{
	DNode *node = CreateDNode(0);
	node->prev = head;
	node->next = head->next;
	head->next->prev = node;
	head->next = node;
}
void DNodePushBack(DNode *head,DataType data)
{
	DNode *node = CreateDNode(0);
	node->prev = head->prev;
	node->next;
	node = head->prev->next;
	head->prev = node;

}
void DListInsert(DNode *head, DataType data)
{
	DNode *node = CreateDNode(data);
	node->prev = head->prev;
	node->next = head;
	head->prev->next = node;
	head->prev = node;

}
void DListPopFront(DNode *head)
{
	assert(head->next != head);
	DNode *first = head->next;
	DNode *second = head->next->next;
	head->next = second;
	second->prev = head;
	head->next = head;
	
}
void DListPopBack(DNode *head)
{
	assert(head->next != head);
	DNode *node;
	node->prev->next = head;
	head->prev = node->prev;
	free(node);
}
void DListErase(DNode *head, DNode *pos)
{
	assert(head->next != head);
	pos->prev->next = pos->next;
	pos->next->prev = pos->prev;
	free(pos);
}
void DListClear(DNode *head)
{
	DNode *next;
	for (DNode *cur = head->next; cur != head; cur = next)
	{
		next = cur->next;
		free(cur);
	}
	head->prev = head->next = head;
}
void DNodePrintf(DNode *head)
{
	for (DNode *cur = head->next; cur != head; cur = cur->next)
	{
		printf("%d", cur->data);
	}
	printf("\n");
}
void Test()
{
	DNode *List;
	DNodeInit(&List);
	DNodePushBack(List, 1);
	DNodePushBack(List, 2);
	DNodePushBack(List, 3);
	DNodePushBack(List, 4);
	DNodePushBack(List, 5);
	DNodePrintf(List);

}

双向带头循环链表时间复杂度O(1),因为是循环首位相接,不管是头,尾相加节点都可以直接确定位置,并不需要遍历(除去clear,和打印链表必须要遍历链表)。

我们在增删查改双向带头链表时候,需要注意的是该表head,最后节点
的指向,以及将原有指向关系换成新的指向关系。注意增删改查,对
链表指向关系改变的影响这个是关键,也是需要注意的。**以及我们
需要注意在clear不能删除头节点,在节点修改时候,我们需要保证头
节点安全,不能破环这个,匿名如果简单实现循环带头双链表为题会
简单很多的。

猜你喜欢

转载自blog.csdn.net/sing_Hwang/article/details/85092351