双向循环链表在单向循环链表的基础上,结点的结构体内多一个成员,即指向上一个结点的地址的指针域。这就使得双向循环链表在插入、删除等操作中,可以根据插入、删除的位置,判断和结点的距离,从而选择采用从头遍历还是从尾遍历,相较于单向循环链表对于大量数据的处理能够提高效率,但是选择了牺牲一部分空间来存储指向上一个结点的地址。
下面的dlinklist.c含双向循环链表的相关操作函数,main.c用于测试该链表。
运行结果:
/*
dlinklist.h
*/
#include <stdio.h>
#include <stdlib.h>
#ifndef __DLINKLIST__
#define __DLINKLIST__
typedef int data_t;
typedef struct dlinklist{
data_t data;
struct dlinklist *prior;
struct dlinklist *next;
}DLinkList,Node;
//创建结点
DLinkList *Create_DLinklist();
//头插法
void DLinklist_Insert_Head(DLinkList *head,data_t data);
//计算表长
int DLinklist_Len(DLinkList *head);
//按位置删除 定位到位置 调用Delete()
void DLinklist_Delete_Pos(DLinkList *head,int pos);
//输入待删除结点地址进行删除
void Delete(DLinkList *p);
//打印
void Show_DLinklist(DLinkList *head);
#endif
/*
dlinklist.c
*/
#include "dlinklist.h"
//创建结点
DLinkList *Create_DLinklist()
{
DLinkList *head = (DLinkList *)malloc(sizeof(DLinkList));
if(head == NULL){
printf("malloc failed!\n");
return NULL;
}
head->data = -1;
head->prior = head;
head->next = head;
return head;
}
//头插法
void DLinklist_Insert_Head(DLinkList *head,data_t data)
{
Node *new = (Node *)malloc(sizeof(Node));
if(new == NULL){
printf("Node malloc failed!\n");
return;
}
new->data = data;
//先完成新结点后的结点 的连接,再进行和头结点的连接
head->next->prior = new;
new->next = head->next;
head->next = new;//该语句需在前两条之后,执行该语句会改变head->next的指向
new->prior = head;
}
//计算表长
int DLinklist_Len(DLinkList *head)
{
Node *p = head;
int len = 0;
while(p->next != head){
len++;
p = p->next;
}
return len;
}
//按位置删除 头结点后一个结点pos为1
void DLinklist_Delete_Pos(DLinkList *head,int pos)
{
//判断插入位置是否合理
Node *p = head;
int len = DLinklist_Len(head);
if(len-pos >= pos){//插入位置靠近头 从头遍历
while(pos--){//遍历到要删除的位置
p = p->next;
}
Delete(p);
}else{//插入位置靠近尾 从尾遍历
int i = len-pos+1;
while(i--){
p = p->prior;
}
Delete(p);
}
}
//删除结点 输入待删除结点的地址
void Delete(DLinkList *p){
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);
}
//打印
void Show_DLinklist(DLinkList *head)
{
Node *p = head;
while(p->next != head){
p = p->next;
printf("%d ",p->data);
}
puts("");
}
/*
main.c
*/
#include "dlinklist.h"
int main()
{
DLinkList *dlink = Create_DLinklist();
int n = 10;
while(n--){//初始化一条链表
DLinklist_Insert_Head(dlink,n);
}
Show_DLinklist(dlink);
printf("Initial len = %d\n",DLinklist_Len(dlink));
DLinklist_Delete_Pos(dlink,1);
printf("\nAfter delete first one len = %d\n",DLinklist_Len(dlink));
Show_DLinklist(dlink);
DLinklist_Delete_Pos(dlink,9);
printf("\nAfter delete last one len = %d\n",DLinklist_Len(dlink));
Show_DLinklist(dlink);
return 0;
}