在之前的博客里我们讲到了不带头节点不带环的单向链表,今天我们来实现一个有头结点有环的双向链表。
我们首先设置一个头结点,这个头结点的数据是无意义的,我们再设置一个环,让这个链表的尾巴指向头称为一个带环链表。相比于之前的单向链表,这次我们多加了一个prev指针,成为双向链表。如图就是我们的有头有环的双向链表。画的太丑了....
话不多说,直接看代码
DLinkList.h
#pragma once #include <stdio.h> #include <stdlib.h> typedef char DLinkType; typedef struct DLinkNode{ DLinkType data; struct DLinkNode* next; struct DLinkNode* prev; }DLinkNode; void DLinkListInit(DLinkNode** head);//初始化 void DLinkListPushBack(DLinkNode* head,DLinkType value);//尾插 void DLinkListPopBack(DLinkNode* head);//尾删 void DLinkListPushFront(DLinkNode* head,DLinkType value);//头插 void DLinkListPopFront(DLinkNode* head);//头删 DLinkNode* DLinkListFind(DLinkNode* head,DLinkType to_find);//查找 void DLinkListInsertBefore(DLinkNode* pos,DLinkType value);//任意位置之前插入 void DLinkListInsertAfter(DLinkNode* pos,DLinkType value);//任意位置之后插入 void DLinkListErase(DLinkNode* pos);//任意位置删除 void DLinkListRemove(DLinkNode* head,DLinkType to_delete);//根据元素删除链表中第一个指定元素 void DLinkListRemoveAll(DLinkNode* head,DLinkType to_delete);//根据元素删除链表中所有指定元素 size_t DLinkListSize(DLinkNode* head);//链表长度 int DLinkListEmpty(DLinkNode* head);//判断链表是否为空DLinkList.c
#include <stdio.h>
#include <stdlib.h>
#include "DLinkList.h"
DLinkNode* CreatDNode(DLinkType value){//创建新结点
DLinkNode* ptr = (DLinkNode*)malloc(sizeof(DLinkNode));
ptr->data = value;
ptr->next = ptr;
ptr->prev = ptr;
return ptr;
}
void DLinkListPrint(DLinkNode* head){//打印函数
DLinkNode* cur1 = head->next;
DLinkNode* cur2 = head->prev;
while(cur1 != head){
printf("[%c|%p] ",cur1->data,cur1);
cur1 = cur1->next;
}
printf("\n");
while(cur2 != head){
printf("[%c|%p] ",cur2->data,cur2);
cur2 = cur2->prev;
}
printf("\n");
}
void DLinkListInit(DLinkNode** head){//初始化
if(head == NULL){
return;
}
*head = CreatDNode(0);
}
void DLinkListPushBack(DLinkNode* head,DLinkType value){//尾插
if(head == NULL){
return;
}
DLinkNode* tail = head->prev;
DLinkNode* new_node = CreatDNode(value);
tail->next = new_node;
new_node->prev = tail;
head->prev = new_node;
new_node->next = head;
}
void Destory(DLinkNode* cur)//销毁函数
{
free(cur);
}
void DLinkListPopBack(DLinkNode* head)//尾删
{
if(head == NULL)
{
return;
}
DLinkNode* delete = head->prev;
DLinkNode* tail = delete->prev;
tail->next = head;
head->prev = tail;
Destory(delete);
}
void DLinkListPushFront(DLinkNode* head,DLinkType value)//头插
{
if(head == NULL)
{
return;
}
DLinkNode* new_node = CreatDNode(value);
DLinkNode* after = head->next;
head->next = new_node;
new_node->prev = head;
new_node->next = after;
after->prev = new_node;
}
void DLinkListPopFront(DLinkNode* head)//头删
{
if(head == NULL)
{
return;
}
DLinkNode* delete = head->next;
DLinkNode* after = delete->next;
head->next = after;
after->prev = head;
Destory(delete);
}
DLinkNode* DLinkListFind(DLinkNode* head,DLinkType to_find)//查找元素
{
if(head == NULL)
{
return;
}
DLinkNode* cur = head->next;
while(cur != head)
{
if(cur->data == to_find)
{
return cur;
}
else
{
cur = cur->next;
}
}
return NULL;
}
void DLinkListInsertBefore(DLinkNode* pos,DLinkType value)//任意位置之前插入
{
if(pos == NULL)
{
return;
}
DLinkNode* before = pos->prev;
DLinkNode* new_node = CreatDNode(value);
before->next = new_node;
new_node->prev = before;
new_node->next = pos;
pos->prev = new_node;
}
void DLinkListInsertAfter(DLinkNode* pos,DLinkType value)//任意位置之后插入
{
if(pos == NULL)
{
return;
}
DLinkNode* after = pos->next;
DLinkNode* new_node = CreatDNode(value);
pos->next = new_node;
new_node->prev = pos;
new_node->next = after;
after->prev = new_node;
}
void DLinkListErase(DLinkNode* pos)//任意位置删除
{
if(pos == NULL)
{
return;
}
DLinkNode* after = pos->next;
DLinkNode* before = pos->prev;
before->next = after;
after->prev = before;
Destory(pos);
}
void DLinkListRemove(DLinkNode* head,DLinkType value)//根据元素删除链表中第一个指定元素
{
if(head == NULL)
{
return;
}
DLinkListErase(DLinkListFind(head,value));
}
void DLinkListRemoveAll(DLinkNode* head,DLinkType value)//根据元素删除链表中所有指定元素
{
if(head == NULL)
{
return;
}
DLinkNode* cur = head->next;
while(cur!=head)
{
DLinkListErase(DLinkListFind(head,value));
cur = cur->next;
}
}
size_t DLinkListSize(DLinkNode* head)//链表长度
{
if(head == NULL)
{
return;
}
size_t i = 0;
DLinkNode* cur = head->next;
while(cur!= head)
{
i++;
cur = cur->next;
}
return i;
}
int DLinkListEmpty(DLinkNode* head)//判断链表是否为空
{
if(head == NULL)
{
return -1;
}
if(head->next == head)
{
return 0;
}
else
{
return 1;
}
}
//test.c 测试函数
void test_DLinkListPushBack(){
printf("*******尾插*******\n");
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head,'a');
DLinkListPushBack(head,'b');
DLinkListPushBack(head,'c');
DLinkListPushBack(head,'d');
DLinkListPrint(head);
}
void test_DLinkListPopBack(){
printf("*******尾删*******\n");
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head,'a');
DLinkListPushBack(head,'b');
DLinkListPushBack(head,'c');
DLinkListPushBack(head,'d');
DLinkListPrint(head);
DLinkListPopBack(head);
DLinkListPrint(head);
}
void test_DLinkListPushFront(){
printf("*******头插*******\n");
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushFront(head,'a');
DLinkListPushFront(head,'b');
DLinkListPushFront(head,'c');
DLinkListPushFront(head,'d');
DLinkListPrint(head);
}
void test_DLinkListPopFront(){
printf("*******头删*******\n");
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head,'a');
DLinkListPushBack(head,'b');
DLinkListPushBack(head,'c');
DLinkListPushBack(head,'d');
DLinkListPrint(head);
DLinkListPopFront(head);
DLinkListPrint(head);
}
void test_DLinkListFind(){
printf("*******查找元素*******\n");
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head,'a');
DLinkListPushBack(head,'b');
DLinkListPushBack(head,'c');
DLinkListPushBack(head,'d');
DLinkListPrint(head);
DLinkNode* i = DLinkListFind(head,'b');
printf("找到b元素的地址为:%p\n",i);
}
void test_DLinkListInsertBefore(){
printf("*******任意位置之前插入元素*******\n");
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head,'a');
DLinkListPushBack(head,'b');
DLinkListPushBack(head,'c');
DLinkListPushBack(head,'d');
DLinkListPrint(head);
DLinkListInsertBefore(DLinkListFind(head,'c'),'m');
DLinkListPrint(head);
}
void test_DLinkListInsertAfter(){
printf("*******任意位置之后插入元素*******\n");
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head,'a');
DLinkListPushBack(head,'b');
DLinkListPushBack(head,'c');
DLinkListPushBack(head,'d');
DLinkListPrint(head);
DLinkListInsertAfter(DLinkListFind(head,'c'),'m');
DLinkListPrint(head);
}
void test_DLinkListErase(){
printf("*******任意位置删除元素*******\n");
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head,'a');
DLinkListPushBack(head,'b');
DLinkListPushBack(head,'c');
DLinkListPushBack(head,'d');
DLinkListPrint(head);
DLinkListErase(DLinkListFind(head,'b'));
DLinkListPrint(head);
}
void test_DLinkListRemove(){
printf("*******根据元素值删除链表中第一个指定元素*******\n");
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head,'a');
DLinkListPushBack(head,'b');
DLinkListPushBack(head,'b');
DLinkListPushBack(head,'c');
DLinkListPushBack(head,'d');
DLinkListPrint(head);
DLinkListRemove(head,'b');
DLinkListPrint(head);
}
void test_DLinkListRemoveAll(){
printf("*******根据元素值删除链表中所有指定元素*******\n");
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head,'a');
DLinkListPushBack(head,'b');
DLinkListPushBack(head,'b');
DLinkListPushBack(head,'c');
DLinkListPushBack(head,'d');
DLinkListPrint(head);
DLinkListRemoveAll(head,'b');
DLinkListPrint(head);
}
void test_DLinkListSize(){
printf("*******链表长度*******\n");
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head,'a');
DLinkListPushBack(head,'b');
DLinkListPushBack(head,'c');
DLinkListPushBack(head,'d');
DLinkListPrint(head);
size_t i = DLinkListSize(head);
printf("链表长度为:%d\n",i);
}
void test_DLinkListEmpty()
{
printf("*******判断链表是否为空*******\n");
DLinkNode* head;
DLinkListInit(&head);
int i = DLinkListEmpty(head);
printf("返回值为:%d\n",i);
}
int main() //main函数
{
test_DLinkListPushBack();
test_DLinkListPopBack();
test_DLinkListPushFront();
test_DLinkListPopFront();
test_DLinkListFind();
test_DLinkListInsertBefore();
test_DLinkListInsertAfter();
test_DLinkListErase();
test_DLinkListRemove();
test_DLinkListRemoveAll();
test_DLinkListSize();
test_DLinkListEmpty();
}
运行结果