尾插
尾删
头插
头删
查找元素在链表中的位置
往指定位置之前插入一个元素
往指定位置之后插入一个元素
删除指定位置的元素
删除指定值的元素
删除指定值的所有元素
具体代码如下:
①dlinklist.h
#pragma once
#include <stddef.h>
#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 DLinkListPopBack(DLinkNode* head); //尾删
void DLinkListPushFront(DLinkNode* head, DLinkType value); //头插
void DLinkListPopFront(DLinkNode* head); //头删
DLinkNode* DLinkListFind(DLinkNode* head, DLinkType to_find); //查找元素在链表中的位置
void DLinkListInsert(DLinkNode* pos, DLinkType value); //往指定位置之前插入一个元素
void DLinkListInsertAfter(DLinkNode* pos, DLinkType value); //往指定位置之后插入一个元素
void DLinkListErase(DLinkNode* head, DLinkNode* pos); //删除指定位置的元素
void DLinkListRemove(DLinkNode* head, DLinkType value); //删除指定值的元素
void DLinkListRemoveAll(DLinkNode* head, DLinkType value); //删除指定值的所有元素
size_t DLinkListSize(DLinkNode* head); //求链表元素个数
int DLinkListEmpty(DLinkNode* head); //判断链表是否为空,为空返回1,否则返回0
void DLinkListDestroy(DLinkNode** head); //销毁链表
②dlinklist.c
#include "dlinklist.h"
#include <stdlib.h>
#include <assert.h>
DLinkNode* CreateDLinkListNode(DLinkType value)
{
DLinkNode* ptr = (DLinkNode*)malloc(sizeof(DLinkNode));
ptr->data = value;
ptr->next = ptr;
ptr->prev = ptr;
return ptr;
}
void DestroyDLinkListNode(DLinkNode* ptr)
{
free(ptr);
}
void DLinkListInit(DLinkNode** head)
{
if (head == NULL)
{
return; //非法输入
}
*head = CreateDLinkListNode(0);
return;
}
DLinkNode* DLinkListPushBack(DLinkNode* head, DLinkType value) //尾插
{
if (head == NULL)
{
return NULL; //非法输入
}
DLinkNode* new_node = CreateDLinkListNode(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 DLinkListPopBack(DLinkNode* head) //尾删
{
if (head == NULL)
{
return; //非法输入
}
if (head->next == head)
{
return; //空链表
}
DLinkNode* to_delete = head->prev;
DLinkNode* to_delete_next = to_delete->next;
DLinkNode* to_delete_prev = to_delete->prev;
to_delete_prev->next = to_delete_next;
to_delete_next->prev = to_delete_prev;
DestroyDLinkListNode(to_delete);
to_delete = NULL;
return;
}
void DLinkListPushFront(DLinkNode* head, DLinkType value) //头插
{
if (head == NULL)
{
return; //非法输入
}
DLinkNode* new_node = CreateDLinkListNode(value);
DLinkNode* new_node_next = head->next;
DLinkNode* new_node_prev = head;
new_node_next->prev = new_node;
new_node->next = new_node_next;
new_node_prev->next = new_node;
new_node->prev = new_node_prev;
}
void DLinkListPopFront(DLinkNode* head) //头删
{
if (head == NULL)
{
return; //非法输入
}
if (head == head->next)
{
return; //空链表
}
//DLinkNode* to_delete = head->next;
//DLinkNode* to_delete_next = to_delete->next;
//DLinkNode* to_delete_prev = to_delete->prev;
//to_delete_prev->next = to_delete_next;
//to_delete_next->prev = to_delete_prev;
//DestroyDLinkListNode(to_delete);
//to_delete = NULL;
DLinkListErase(head, head->next);
return;
}
DLinkNode* DLinkListFind(DLinkNode* head, DLinkType to_find) //查找元素在链表中的位置
{
if (head == NULL)
{
return NULL; //非法输入
}
if (head == head->next)
{
return NULL; //空链表
}
DLinkNode* cur = head->next;
for (; cur != head; cur = cur->next)
{
if (cur->data == to_find)
{
return cur;
}
}
return NULL;
}
void DLinkListInsert(DLinkNode* pos, DLinkType value) //往指定位置之前插入一个元素
{
if (pos == NULL)
{
return; //非法输入
}
DLinkNode* new_node = CreateDLinkListNode(value);
DLinkNode* new_node_next = pos;
DLinkNode* new_node_prev = pos->prev;
new_node_next->prev = new_node;
new_node->next = new_node_next;
new_node_prev->next = new_node;
new_node->prev = new_node_prev;
return;
}
void DLinkListInsertAfter(DLinkNode* pos, DLinkType value) //往指定位置之后插入一个元素
{
if (pos == NULL)
{
return; //非法输入
}
DLinkNode* new_node = CreateDLinkListNode(value);
DLinkNode* new_node_next = pos->next;
DLinkNode* new_node_prev = pos;
new_node_next->prev = new_node;
new_node->next = new_node_next;
new_node_prev->next = new_node;
new_node->prev = new_node_prev;
return;
}
void DLinkListErase(DLinkNode* head, DLinkNode* pos) //删除指定位置的元素
{
if (head == NULL || pos == NULL)
{
return; //非法输入
}
if (head == head->next)
{
return; //空链表
}
DLinkNode* pos_prev = pos->prev;
DLinkNode* pos_next = pos->next;
pos_prev->next = pos_next;
pos_next->prev = pos_prev;
DestroyDLinkListNode(pos);
pos = NULL;
return;
}
void DLinkListRemove(DLinkNode* head, DLinkType value) //删除指定值的元素
{
if (head == NULL)
{
return; //非法输入
}
DLinkNode* to_find = head->next;
for (; to_find != head; to_find = to_find->next)
{
if (to_find->data == value)
break;
}
if (to_find != head)
{
DLinkNode* to_delete_prev = to_find->prev;
DLinkNode* to_delete_next = to_find->next;
to_delete_prev->next = to_delete_next;
to_delete_next->prev = to_delete_prev;
DestroyDLinkListNode(to_find);
}
return;
}
void DLinkListRemoveAll(DLinkNode* head, DLinkType value) //删除指定值的所有元素
{
if (head == NULL)
{
return; //非法输入
}
while (1)
{
DLinkNode* pos = DLinkListFind(head, value);
if (pos == NULL)
{
return;
}
DLinkListErase(head, pos);
}
return;
}
size_t DLinkListSize(DLinkNode* head) //求链表元素个数
{
if (head == NULL)
{
return (size_t)-1;
}
size_t count = 0;
DLinkNode* cur = head->next;
for (; cur != head; cur = cur->next)
{
++count;
}
return count;
}
int DLinkListEmpty(DLinkNode* head) //判断链表是否为空,为空返回1,否则返回0
{
assert(head);
if (head->next == head)
{
return 1;
}
return 0;
}
void DLinkListDestroy(DLinkNode** head) //销毁链表
{
if (head == NULL)
{
return; //非法输入
}
if (*head == NULL)
{
return; //该链表带头结点,头指针不可能指向空
}
if ((*head) == (*head)->next)
{
//空链表
DestroyDLinkListNode(*head);
*head = NULL;
return;
}
DLinkNode* cur = (*head)->next;
while (cur != *head)
{
DLinkNode* next = cur->next;
DestroyDLinkListNode(cur);
cur = next;
}
DestroyDLinkListNode(*head);
*head = NULL;
return;
}
③test.c
#include "dlinklist.h"
#include <windows.h>
#define TEST_HEADER printf("\n===========================%s===========================\n",__FUNCTION__)
void DLinkListPrintChar(DLinkNode* head, const char* msg)
{
printf("[%s]:", msg);
printf("[head]");
DLinkNode* cur = head->next;
for (; cur != head; cur = cur->next)
{
printf(" -> [%c:%p]", cur->data, cur);
}
printf("\n");
printf(" ");
printf("[head]");
for (cur = head->prev; cur != head; cur = cur->prev)
{
printf(" -> [%c:%p]", cur->data, cur);
}
printf("\n");
}
void TestInit()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
printf("head = %p\n", head);
printf("head->next = %p\n", head->next);
printf("head->prev = %p\n", head->prev);
}
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, "尾插四个元素");
DLinkListPopBack(head);
DLinkListPopBack(head);
DLinkListPrintChar(head, "尾删两个元素");
DLinkListPopBack(head);
DLinkListPopBack(head);
DLinkListPrintChar(head, "尾删两个元素");
DLinkListPopBack(head);
DLinkListPrintChar(head, "对空链表尾删");
}
void TestPushFront()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushFront(head, 'd');
DLinkListPushFront(head, 'c');
DLinkListPushFront(head, 'b');
DLinkListPushFront(head, 'a');
DLinkListPrintChar(head, "头插四个元素");
}
void TestPopFront()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushFront(head, 'd');
DLinkListPushFront(head, 'c');
DLinkListPushFront(head, 'b');
DLinkListPushFront(head, 'a');
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);
DLinkNode* pos = DLinkListFind(head, 'a');
printf("[对空链表查找]:");
printf("pos expect NULL, actual %p\n", pos);
DLinkListPushBack(head, 'a');
DLinkNode* pos_b = DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插四个元素");
pos = DLinkListFind(head, 'b');
printf("[查找元素b]:");
printf("pos expect %p, actual %p\n", pos_b, pos);
pos = DLinkListFind(head, 'x');
printf("[查找不存在元素x]:");
printf("pos expect NULL, actual %p\n", pos);
}
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(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');
DLinkNode* pos_b = DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插四个元素");
DLinkListErase(head, pos_b);
DLinkListPrintChar(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, 'a');
DLinkListPrintChar(head, "删除元素a 后");
DLinkListRemove(head, 'x');
DLinkListPrintChar(head, "删除不存在元素x");
}
void TestRemoveAll()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插六个元素");
DLinkListRemoveAll(head, 'c');
DLinkListPrintChar(head, "删除元素c 后");
DLinkListRemoveAll(head, 'x');
DLinkListPrintChar(head, "删除不存在元素x");
}
void TestSize()
{
TEST_HEADER;
DLinkNode* head = NULL;
size_t size = DLinkListSize(head);
printf("size expect (size_t)-1, actual %lu\n", size);
DLinkListInit(&head);
size = DLinkListSize(head);
printf("size expect 0, actual %lu\n", size);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插六个元素");
size = DLinkListSize(head);
printf("size expect 6, actual %lu\n", size);
}
void TestEmpty()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
int ret = DLinkListEmpty(head);
printf("ret expect 1, actual %d\n", ret);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插四个元素");
ret = DLinkListEmpty(head);
printf("ret expect 0, actual %d\n", ret);
}
void TestDestroy()
{
TEST_HEADER;
DLinkNode* head = NULL;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPrintChar(head, "尾插四个元素");
DLinkListDestroy(&head);
printf("[销毁链表后]:head expect NULL, actual %p\n", head);
}
int main()
{
TestInit();
TestPushBack();
TestPopBack();
TestPushFront();
TestPopFront();
TestFind();
TestInsert();
TestInsertAfter();
TestErase();
TestRemove();
TestRemoveAll();
TestSize();
TestEmpty();
TestDestroy();
system("pause");
return 0;
}
结果: