带头节点双向链表有两个指针分别指向前一个节点(prev)和后一个节点(next);用图可以表示为:
DLinkList.h
#define _CRT_SECURE_NO_WARNINGS 1
#include
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);
/**
* * @brief 往指定位置之前插入一个元素
*/
void DLinkListInsert(DLinkNode* pos, DLinkType value);
/**
* * @brief 往指定位置之后插入一个元素
* */
void DLinkListInsertAfter(DLinkNode* pos, DLinkType value);
void DLinkListErase(DLinkNode* head, DLinkNode* pos);
void DLinkListRemove(DLinkNode* head,DLinkType to_find);
void DLinkListRemoveAll(DLinkNode* head, DLinkType to_find);
size_t DLinkListSize(DLinkNode* head);
int DLinkListEmpty(DLinkNode* head);
DLinkList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "DLinkList.h"
#include
void DLinkListFree(DLinkNode* to_delete){
/*
释放空间
*/
free(to_delete);
}
DLinkNode* CreatNode(DLinkType value){
DLinkNode* ptr = (DLinkNode*)malloc(sizeof(DLinkNode));
if (ptr == NULL){
return NULL;
}
ptr->data = value;//NULL<--data-->NULL
ptr->next = NULL;
ptr->prev = NULL;
return ptr;
}
void DLinkListInit(DLinkNode** head){
DLinkNode* new_node = CreatNode(0);
*head =new_node;
(*head)->next = new_node;
(*head)->prev = new_node;
return;
}
DLinkNode* DLinkListPushBack(DLinkNode* head, DLinkType value){
if (head == NULL){
//非法输入
return NULL;
}
DLinkNode* new_node = CreatNode(value);
if (head->next == head){
//head---new_node
head->next = new_node;
head->prev = new_node;
new_node->next = head;
new_node->prev = head;
return head;
}
DLinkNode* pre = head->prev;
pre->next = new_node;
new_node->prev = pre;
new_node->next = head;
head->prev = new_node;
return head;
}
void DLinkListPopBack(DLinkNode* head)
{
if (head == NULL||head->next==head){
return;
}
DLinkNode* to_delete = head->prev;
head->prev = to_delete->prev;
to_delete->prev->next = head;
DLinkListFree(to_delete);
return;
}
void DLinkListPushFront(DLinkNode* head, DLinkType value)
{
if (head == NULL){
return;
}
DLinkNode* new_node = CreatNode(value);
if (head->next == head){
head->next = new_node;
head->prev = new_node;
new_node->next = head;
new_node->prev = head;
return;
}
DLinkNode* next = head->next;
//new_node--next
new_node->next = next;
next->prev = new_node;
new_node->prev=head;
head->next = new_node;
//new_node---head
}
void DLinkListPopFront(DLinkNode* head)
{
if (head == NULL||head->next==head){
//非法输入
return;
}
DLinkNode* to_delete = head->next;
head->next = to_delete->next;
to_delete->next->prev = head;
DLinkListFree(to_delete);
return;
}
DLinkNode* DLinkListFind(DLinkNode* head, DLinkType to_find)
{
if (head == NULL){
//非法输入
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)
{
DLinkNode* new_node = CreatNode(value);
DLinkNode* pre = pos->prev;
new_node->next = pos;
pos->prev = new_node;
pre->next = new_node;
new_node->prev = pre;
return;
}
void DLinkListInsertAfter(DLinkNode* pos, DLinkType value)
{
DLinkNode* new_node = CreatNode(value);
DLinkNode* nex = pos->next;
new_node->next = nex;
nex->prev = new_node;
pos->next = new_node;
new_node->prev = pos;
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;
}
//测试代码//
#define PrintHeader printf("\n------------------%s-----------\n",__FUNCTION__)
void PrintChar(DLinkNode* head, DLinkType *msg)
{
if (head == NULL) {
//非法输入
return;
}
printf("[%s]\n", msg);
DLinkNode* cur = head->next;
for (; cur != head; cur = cur->next){
printf("[%c] ", cur->data);
}
printf("\n");
for (cur=head->prev; cur != head; cur = cur->prev){
printf("[%c] ", cur->data);
}
printf("\n");
return;
}
void TestInit(){
PrintHeader;
DLinkNode* head;
DLinkListInit(&head);
printf("expect NULL,actuall %p\n", head);
printf("expect NULL,actuall %d\n", (int)head->data);
}
void TestPushBack(){
PrintHeader;
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
PrintChar(head, "尾插四个元素");
}
void TestPopBack(){
PrintHeader;
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
DLinkListPopBack(head);
PrintChar(head, "尾删一个元素");
}
void TestPushFront(){
PrintHeader;
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushFront(head, 'a');
DLinkListPushFront(head, 'b');
DLinkListPushFront(head, 'c');
DLinkListPushFront(head, 'd');
PrintChar(head, "头插四个元素");
}
void TestPopFront(){
PrintHeader;
DLinkNode* head;
DLinkListInit(&head);
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
PrintChar(head, "尾插四个元素");
DLinkListPopFront(head);
DLinkListPopFront(head);
PrintChar(head, "头删两个元素");
}
void TestDLinkListFind(){
PrintHeader;
DLinkNode* head;
DLinkListInit(&head);
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
PrintChar(head, "尾插四个元素");
DLinkNode* ret = DLinkListFind(head, 'c');
printf("expect c,actual %c\n", ret->data);
}
void TestInsert(){
PrintHeader;
DLinkNode* head;
DLinkListInit(&head);
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
PrintChar(head, "尾插四个元素");
DLinkListInsert(head->next->next->next, 'X');
PrintChar(head, "在c前插入字符X");
}
void TestInsertAfter(){
PrintHeader;
DLinkNode* head;
DLinkListInit(&head);
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
PrintChar(head, "尾插四个元素");
DLinkListInsertAfter(head->next->next, 'X');
PrintChar(head,"在b的后面插入");
}
void TestErase(){
PrintHeader;
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
PrintChar(head, "尾插四个元素");
DLinkListErase(head, head->next->next);
PrintChar(head, "删除b");
}
void TestRemove(){
PrintHeader;
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
PrintChar(head, "尾插四个元素");
DLinkListRemove(head, 'c');
PrintChar(head, "删除c");
}
void TestRemoveAll(){
PrintHeader;
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
PrintChar(head, "尾插四个元素");
DLinkListRemoveAll(head, 'c');
PrintChar(head, "删除所有的c");
}
void TestDLinkListSize(){
PrintHeader;
DLinkNode* head;
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'd');
size_t ret = DLinkListSize(head);
printf("expect 5,actual %u\n", ret);
}
void TestDLinkListEmpty(){
PrintHeader;
DLinkNode* head;
DLinkListInit(&head);
int ret1 = DLinkListEmpty(head);
printf("expect 0,actual %d\n", ret1);
DLinkListInit(&head);
DLinkListPushBack(head, 'a');
DLinkListPushBack(head, 'c');
DLinkListPushBack(head, 'b');
DLinkListPushBack(head, 'c');
PrintChar(head, "尾插四个元素");
int ret2 = DLinkListEmpty(head);
printf("expect 1,actual %d\n", ret2);
}
///main函数调用
int main()
{
TestInit();//初始化
TestPushBack();//尾插
TestPopBack();//尾删
TestPushFront();//前插
TestPopFront();//前删
TestDLinkListFind();//在链表中找value
TestInsert();//指定位置后插入
TestInsertAfter();//指定位置前插
TestErase();//删除指定位置节点
TestRemove();//删除一个指定字符
TestRemoveAll();//删除所有指定字符
TestDLinkListSize();//求链表的节点数
TestDLinkListEmpty();//判断链表是否为空
system("pause");
return 0;
}
同理,以上的基本操作都需要修改相关节点的两个指针的指向