双向循环链表的实现
双向循环链表结构图
具体函数操作如下:
(1)动态申请节点
DCListNode* BuyDCListNode(DLDataType x)// 动态申请节点
{
DCListNode* newNode = (DCListNode*)malloc(sizeof(DCListNode));
if (NULL == newNode)
{
assert(0);
return NULL;
}
newNode->data = x;
newNode->next = NULL;
newNode->prev = NULL;
return newNode;
}
(2)初始化
申请好头节点,头节点的前驱和后继都指向自己
DCListNode* DCListInit()// 初始化
{
//只需要申请好头节点
DCListNode* head = BuyDCListNode(0);
head->next = head;
head->prev = head;
return head;
}
(3)将有效节点都清除
这里采取头删的方法清除有效节点,头删方法的具体实现下面会仔细解释。在对双向链表进行遍历时,需要对指针加以限定,否则会进入无限循环的状态,判断循环指针是否等于头节点即可。
清除有效节点后,元素为空,所以需要将头指针的前驱和后继指向自己。
void DCListClear(DCListNode* pHead)// 将有效节点清除
{
assert(pHead);
DCListNode* tail = pHead->next;
while (tail != pHead)
{
//采用头删的方法
pHead->next = tail->next;
free(tail);
tail = pHead->next;
}
//链表为空
pHead->next = pHead;
pHead->prev = pHead;
}
(4)销毁
在进行销毁操作时,需要将头节点和有效节点都进行清除,调用清除的函数,然后将头节点进行删除设置为空,避免成为野指针。
void DCListDestory(DCListNode** pHead)// 双向链表销毁 头节点和有效节点都需要进行清除
{
assert(pHead);
DCListClear(*pHead);
free(*pHead);
*pHead = NULL;
}
(5)双向链表的打印
void DCListPrint(DCListNode* head)// 双向链表打印
{
DCListNode* tail = head->next;
while (tail != head)
{
printf("%d ", tail->data);
tail = tail->next;
}
printf("\n");
}
(6)双向链表的长度
完成链表的遍历后,使用count进行计数,则可得到链表的长度
int DCListSize(DCListNode* pHead) //双向链表长度
{
assert(pHead);
DCListNode* tail = pHead->next;
int count = 0;
while (tail != pHead)
{
++count;
tail = tail