双向循环链表:每个节点都含有指向上一个节点(pre)和下一个节点(next)的指针,因此整个链表可以往两个方向,最后一个节点的next指向头结点,头结点的pre指向尾节点,因此是循环链表。
节点数据:
typedef int datatype;
typedef struct list{
datatype data;
struct list *pre,*next;
}doublelist,*pdoublelist;
/* 初始化双向链表头结点 */
void DoubleList_Init(pdoublelist *Head)
{
*Head = (pdoublelist)malloc(sizeof(doublelist));
if(NULL == *Head)
{
perror("malloc");
exit(1);
}
/* 让头结点的pre和next指向自己 */
(*Head)->pre = *Head;
(*Head)->next = *Head;
}
/* 插入到头节点 */
void DoubleList_InsertHead(pdoublelist Head,pdoublelist node)
{
node->next = Head->next;
Head->next->pre = node;
/* 上下两句代码不可调换 */
node->pre = Head;
Head->next = node;
}
/* 插入到尾节点 */
void DoubleList_InsertTail(pdoublelist Head,pdoublelist node)
{
node->pre = Head->pre;
Head->pre->next = node;
/* 上下两句代码不可调换 */
node->next = Head;
Head->pre = node;
}
/* 删除指定数据的节点 */
int DoubleList_Delete(pdoublelist Head,datatype data)
{
pdoublelist temp = Head;
while(temp->next!=temp)
{
temp = temp->next;
/* 找到要删除的节点 */
if(temp->data==data)
{
temp->next->pre = temp->pre;
temp->pre->next = temp->next;
free(temp);
printf("删除节点成功\n");
return 0;
}
}
printf("没有知道该节点\n");
}
/* 为链表创建指定个节点数据 */
void DoubleList_Create(pdoublelist Head,int n)
{
int i;
pdoublelist new;
datatype input;
for(i = 0; i < n; i++)
{
new = (pdoublelist)malloc(sizeof(doublelist));
if(NULL == new)
{
perror("melloc");
exit(1);
}
printf("请输入第%d个节点的数据:",i+1);
scanf("%d",&new->data);
/* 把新节点放入链表 */
DoubleList_InsertHead(Head,new); //放入到头结点
//DoubleList_InsertTail(Head,new); //放入到尾结点
}
}
/* 遍历双向循环链表 */
void DoubleList_each(pdoublelist Head)
{
pdoublelist temp;
printf("双向链表循环数据:");
for(temp = Head->next; temp!=Head; temp = temp->next)
{
printf(" %d",temp->data);
}
printf("\n");
}
测试程序:
int main(void)
{
datatype data;
pdoublelist head;
DoubleList_Init(&head);
DoubleList_Create(head,5);
DoubleList_each(head);
printf("请输入要删除的数据:");
scanf("%d",&data);
DoubleList_Delete(head,data);
DoubleList_each(head);
}