双向链表

本文详细介绍了双向链表的各种操作实现,包括初始化、插入、删除等,并提供了完整的测试代码示例。
#include<stdio.h>


typedef char DLinkType;


typedef struct DLinkNode {
DLinkType data;
struct DLinkNode* next;
struct DLinkNode* prev;
} DLinkNode;


void DLinkListInit(DLinkNode** head);


DLinkNode* DLinkListPushBack(DLinkNode* head, DLinkType value);


void DLinListPopBack(DLinkNode* head);


void DLinkListPushFront(DLinkNode* head, DLinkType value);


void DLinkListPopFront(DLinkNode* head);


DLinkNode* DLinkListFind(DLinkNode* head, DLinkType to_find);


/**
* @brief 往指定位置之前插入一个元素
*/
void DLinkListInsert(DLinkNode* pos, DLinkType value);


/**
* @brief 往指定位置之后插入一个元素
*/
void DLinkListInsertAfter(DLinkNode* pos, DLinkType value);


void DLinkListErase();


void DLinkListRemove();


void DLinkListRemoveAll();


size_t DLinkListSize();


int DLinkListEmpty();


//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////

#include"Linklist.h"
#pragma once
#include<stddef.h>


DLinkNode* CreateDNode(DLinkType value)
{
DLinkNode* ptr = (DLinkNode*)malloc(sizeof(DLinkNode));
ptr->data = value;
ptr->next = ptr;
ptr->prev = ptr;
return ptr;
}


void DestroyDNode(DLinkNode* ptr)
{
free(ptr);
}




void DLinkListInit(DLinkNode** head)
{
if (head == NULL)
return;//非法输入
*head = CreateDNode(0);
return;
}


DLinkNode* DLinkListPushBack(DLinkNode* head, DLinkType value)
{
if (head == NULL)
return NULL;
//非法输入
DLinkNode* new_node = CreateDNode(value);
DLinkNode* new_node_next = head;
DLinkNode* new_node_prev = head->prev;
new_node_prev->next = new_node;
new_node->prev = new_node->prev;
new_node_next->prev = new_node;
new_node->next = new_node_next;
return new_node;
}


void DLinListPopBack(DLinkNode* head)
{
if (head == NULL)
return;//非法输入
if (head->prev == head)
//head->prev == head->next写法是错误的
return;//空链表
DLinkNode* to_delete = head->prev;
DLinkNode* to_delete_prev = to_delete->prev;
DLinkNode* to_delete_next = to_delete->next;
to_delete_prev->next = to_delete_next;
to_delete_next->prev = to_delete_prev;
DestroyDNode(to_delete);
}


void DLinkListPushFront(DLinkNode* head, DLinkType value)
{
if (head == NULL)
return;//非法输入
DLinkNode* new_node = CreateDNode(value);
DLinkNode* new_node_prev = head;
DLinkNode* new_node_next = head;
new_node_prev->next = new_node;
new_node->prev = new_node_prev;
new_node->next = new_node_next;
new_node_next->prev = new_node;
}


void DLinkListPopFront(DLinkNode* head)
{
if (head == NULL)
return;//非法输入
if (head == head->next)//空链表
return;//不需删除任何元素
DLinkNode* to_delete = head->next;
DLinkNode* to_delete_prev = to_delete->prev;
DLinkNode* to_delete_next = to_delete->next;
to_delete_prev->next = to_delete_next;
to_delete_next->prev = to_delete_prev;
DestroyDNode(to_delete);
return;
}
DLinkNode* DLinkListFind(DLinkNode* head, DLinkType to_find)
{
DLinkNode* cur = head->next;
for (; cur != head; cur = cur->next)
{
if (cur->data == to_find)
return cur;
}
return NULL;
}
/**
* @brief 往指定位置之前插入一个元素
*/
void DLinkListInsert(DLinkNode* head, DLinkNode* pos, DLinkType value)
{
if (head == NULL || pos == NULL)
return;//非法输入
DLinkNode* new_node = CreateDNode(value);


DLinkNode* new_node_prev = pos->prev;
DLinkNode* new_node_next = pos;//第一组指针的相互赋值


new_node->next = new_node_next;
new_node_next->prev = new_node;
return;


}
/**
* @brief 往指定位置之后插入一个元素
*/
void DLinkListInsertAfter(DLinkNode* pos, DLinkType value)
{
if (pos == NULL)
return;
DLinkNode* cur = CreateDNode(value);
DLinkNode* to_prev = pos;
DLinkNode* to_next = pos->next;
cur->prev = to_prev;
to_prev->next = cur;
cur->next = to_next;
to_next->prev = cur;
return;
}
void DLinkListErase(DLinkNode* head,DLinkNode* pos)
{
if (head == NULL || head == pos)
return;//非法输入
DLinkNode* to_delete = pos;
DLinkNode* pre = to_delete->prev;
DLinkNode* nex = to_delete->next;
pre->next = nex;
nex->prev = pre;
DLinkListFree(to_delete);
return;


}
void DLinkListRemove(DLinkNode* head, DLinkType to_find)
{
if (head == NULL)
return;//非法输入
DLinkNode* pos = DLinkListFind(head, to_find);
if (pos == NULL)
return;//没找到
DLinkListErase(head, pos);
return;
}
void DLinkListRemoveAll(DLinkNode* head, DLinkType to_find)
{
if (head == NULL)
return;//非法输入
while (1)
{
DLinkNode* pos = DLinkListFind(head, to_find);
if (pos == NULL)
break;//没找到
DLinkListErase(head, pos);
}
}
size_t DLinkListSize(DLinkNode* head)
{
if (head == NULL || head->next == head)
return 0;
size_t count = 0;
DLinkNode* cur = head->next;
for (; cur != head; cur = cur->next)
{
count++;
}
return count;
}
int DLinkListEmpty(DLinkNode* head)
{
if (head == NULL)
return -1;
if (head->next == head)
return 0;
return 1;
}


//////////////////////////////////////////////////////////
////////////////以下是测试代码////////////////////////////
/////////////////////////////////////////////////////////////
#if 1
#include<stdio.h>


#define TEST_HEADER  printf("\n========================%s=========================\n",__FUNCTION__)


void DLinkListPrintChar(DLinkNode* head,const char* msg)
{
printf("\n[%s]\n", msg);
printf("[head]");
DLinkNode* cur = head->next;
for (; cur != head; cur = cur->next)
{
printf("->[%c:%p]", cur->data, cur);
}
printf("\n");
printf("[head]");
for (cur = head->prev; cur != head; cur = cur->prev)
{
printf("->[%c:%p]", cur->data, cur);
}
}




void TestInit()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
}


void TestPushBack()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插四个元素");
}
void TestPopBack()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插四个元素");
DLinListPopBack(head);
DLinListPopBack(head);
DLinkListPrintChar(head, "尾删两个元素");
DLinListPopBack(head);
DLinListPopBack(head);
DLinkListPrintChar(head, "尾删两个元素");
DLinListPopBack(head);
DLinkListPrintChar(head, "尝试对空链表删除");
}


void TestPushFront()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushFront(head, 'a');
DLinkListPushFront(head, 'b');
DLinkListPushFront(head, 'c');
DLinkListPushFront(head, 'd');
DLinkListPrintChar(head, "头插四个元素");
}


void TestPopFront()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushFront(head, 'a');
DLinkListPushFront(head, 'b');
DLinkListPushFront(head, 'c');
DLinkListPushFront(head, 'd');
DLinkListPrintChar(head, "头插四个元素");
DLinkListPopFront(head);
DLinkListPopFront(head);
DLinkListPrintChar(head, "头删两个元素");
DLinkListPopFront(head);
DLinkListPopFront(head);
DLinkListPrintChar(head, "头删两个元素");
DLinkListPopFront(head);
DLinkListPrintChar(head, "尝试对空链表删除");


}
void TestFind()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkNode* pos_b = DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插四个元素");
DLinkNode* pos_x = DLinkListFind(head, 'x');
printf("pos_x expect NULL,actual %p\n", pos_x);
DLinkNode* tmp = DLinkListFind(head, 'b');
printf("b expect %p,actual %p\n", pos_b, tmp);
}


void TestInsert()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkNode* pos_b = DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插四个元素");
DLinkListInsert(head,pos_b,'x');
DLinkListPrintChar(head, "在b之前插入了x");


}
void TestInsertAfter()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkNode* pos_b = DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插四个元素");
DLinkListInsertAfter(pos_b, 'x');
DLinkListPrintChar(head, "在b之后插入了x");
}
void TestErase()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插四个元素");
DLinkListErase(head, head->next->next);
Printchar(head, "删除b");
}
 void TestRemove()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插四个元素");
DLinkListRemove(head, 'c');
Printchar(head, "删除c");
DLinkListRemoveAll(head, 'c');
Printchar(head, "删除所有的c");
}
void TestRemoveAll()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插四个元素");
}
void TestDLinkListSize()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
size_t ret = DLinkListSize(head);
printf("expect 5,actual %u\n", ret);
}
void TestDLinkListEmpty()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
int ret1 = DLinkListEmpty(head);
printf("expect 0,actual %d\n", ret1);
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插四个元素");
int ret2 = DLinkListEmpty(head);
printf("expect 1,actual %d\n", ret2);
}


int main()
{
TestPushBack();//尾插
TestPopBack();//尾删
TestPushFront();//头插
TestPopFront();//头删
TestFind();//在链表中找value
TestInsert();//指定位置后插入
TestInsertAfter();//指定位置前插入
TestErase();//删除指定位置节点
TestRemove();//删除一个指定字符
TestRemoveAll();//删除所有指定字符
TestDLinkListSize();//求链表的节点数
TestDLinkListEmpty();//判断链表是否为空
return 0;
}
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值