带头节点的双向列表

双向列表都有一个前驱和一个后继,添加或者删除节点可以使用双向列表的这一个特性去做。

.h

#pragma once //防止头文件重复定义

#include<stdio.h>
#include<stdlib.h> 
#include<stddef.h>
typedef char DLinktype; 
typedef struct DLinkNode {
DLinktype data; // 存放数据 
struct DLinkNode* next; //定义后一个节点
struct DLinkNode* prev; //定义前一个节点 
}DLinkNode;
//初始化函数 
void DLinklistInit(DLinkNode** phead); 
//链表尾插 
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 value); 


// 在指定位置之前插入元素 
void DLinklistInsert(DLinkNode* head, DLinkNode* pos, DLinktype value);
// 在指定位置之后插入元素
void DLinklistInsertafter(DLinkNode* head, DLinkNode* pos, DLinktype value); 
//删除指定位置的元素
void DLinklistErase(DLinkNode*head, DLinkNode* to_delete); 
//删除指定值的元素 
void DLinklistRemove(DLinkNode* head, DLinktype to_remove);
//删除指定值的所有元素 
void DLinklistRemoveall(DLinkNode* head, DLinktype to_remove);


//求链表的长度 
size_t DLinklistSize(DLinkNode* head); 
//判断链表是否为空
int DLinklistEmpty(DLinkNode* head); #include"DLinkNode.h"//创建新节点 
DLinkNode* DLinkNodeCreat(DLinktype value) 

DLinkNode* new = (DLinkNode*)malloc(sizeof(DLinkNode)); //创建节点申请空间
new->data = value; 
new->next = NULL;
new->prev = NULL;
return new; 
} //销毁节点 
void DLinkNodeDestroy(DLinkNode* node) 
{
free(node);
node = NULL; } //初始化函数
void DLinklistInit(DLinkNode** phead) 
{
if (phead == NULL)
{
printf("非法输入");
return; 

*phead = DLinkNodeCreat(0); //创建一个不具有实际意义的头节点, 
(*phead)->next = *phead; 
(*phead)->prev = *phead; } //链表尾插
DLinkNode* DLinklistPushback(DLinkNode* head, DLinktype value) 
{ if (head == NULL)
{ printf("非法输入"); 
return NULL; }
DLinkNode* new = DLinkNodeCreat(value);
DLinkNode* tail = head->prev; //head 2-2 
 new->next = head;
head->prev = new; //tail 2-2
 tail->next = new; 
new->prev = tail; 
return new; } //链表尾删 
void DLinklistPopback(DLinkNode* head)
{
if (head == NULL)
{
printf("非法输入"); return;

if (head->next == head || head->prev == head)
{ printf("空链表");
return;
}
DLinkNode* lastone = head->prev;
DLinkNode* lasttwo = lastone->prev; 
lasttwo->next = head;
head->prev = lasttwo; 
DLinkNodeDestroy(lastone);
} //链表头插 
void DLinklistPushfront(DLinkNode* head, DLinktype value) { 
if (head == NULL)
{
printf("非法输入"); 
return;
}
DLinkNode* new = DLinkNodeCreat(value); 
DLinkNode* second = head->next; // sencond new
new->next = second;
second->prev = new; // head new 
head->next = new;
new->prev = head; } //链表头删
void DLinklistPopfront(DLinkNode* head)
{
if (head == NULL)

printf("非法输入");
return; 

if (head->next == head || head->prev == head) 

printf("空链表");
return;

DLinkNode* second = head->next; 
DLinkNode* third = second->next;
head->next = third; 
third->prev = head;
DLinkNodeDestroy(second);
} //查找指定元素的位置
DLinkNode* DLinklistFind(DLinkNode* head, DLinktype to_find)

if (head == NULL) 
{ printf("非法输入"); 
return NULL;
}
DLinkNode* cur = head->next;
while (cur != head)

if (cur->data==to_find)
{
return cur;

cur = cur->next; 

return NULL;
} // 在指定位置之前插入元素
void DLinklistInsert(DLinkNode* head, DLinkNode* pos, DLinktype value)

if (head == NULL || pos == NULL)
{
printf("非法输入"); 
return;
}
DLinkNode* pospre = pos->prev;
DLinkNode* new = DLinkNodeCreat(value); //pospre new 
new->prev = pospre; 
pospre->next = new; //new pos
new->next = pos;
pos->prev = new;
} // 在指定位置之后插入元素
void DLinklistInsertafter(DLinkNode* head, DLinkNode* pos, DLinktype value) 
{
if (head == NULL || pos == NULL)
{
printf("非法输入"); 
return;

DLinkNode* new = DLinkNodeCreat(value);
DLinkNode* posafter = pos->next; // pos new 
pos->next = new; 
new->prev = pos; //new posafter
new->next = posafter;
posafter->prev = new;
} //删除指定位置的元素
void DLinklistErase(DLinkNode*head, DLinkNode* to_delete) 
{
if (head == NULL || to_delete == NULL)

printf("非法输入"); 
return;
}
DLinkNode* after = to_delete->next;
DLinkNode* before = to_delete->prev;
before->next=after; 
after->prev = before; 
DLinkNodeDestroy(to_delete); } //删除指定值的元素
void DLinklistRemove(DLinkNode* head, DLinktype to_remove)
{
if (head == NULL )

printf("非法输入"); 
return;

DLinkNode* pos = DLinklistFind(head, to_remove); 
DLinklistErase(head, pos); } //删除指定值的所有元素 
void DLinklistRemoveall(DLinkNode* head, DLinktype value) 

if (head == NULL) 
{
printf("非法输入"); 
return;
}
DLinkNode* cur = head->next;
while (cur != head) { 
if (cur->data == value)
{
DLinkNode* before = cur->prev;
DLinkNode* after = cur->next;
before->next = after; 
after->prev = before;
DLinkNode* tmp = cur; 
DLinkNodeDestroy(tmp);
cur = before; 
}
cur = cur->next;
}


#include"DLinkNode.h" 


#define FUNCTION() printf("****** %s ***********\n",__FUNCTION__) ; 
void Printchar(DLinkNode* head, const char *msg) 
{ printf("[%s]:\n", msg); if (head == NULL)
{
return;

DLinkNode* cur = head->next; //正序打印 
while (cur != head) 
{
printf("[%c|%p]", cur->data, cur); 
cur = cur->next;
}
printf("\n"); //逆序打印 
DLinkNode* ret = head->prev;
while (ret != head) 

printf("[%c|%p]", ret->data, ret); 
ret = ret->prev;
}
printf("\n");

void TestDInit() { FUNCTION();


DLinkNode* head;
DLinklistInit(&head); 

void TestPushback() 

FUNCTION();
DLinkNode* head;
DLinklistInit(&head);
DLinklistPushback(head, 'a'); 
DLinklistPushback(head, 'b'); 
DLinklistPushback(head, 'c');
DLinklistPushback(head, 'd'); 
Printchar(head, "尾插四个元素");
}
void TestPopback() { FUNCTION();
DLinkNode* head;
DLinklistInit(&head); 


DLinklistPushback(head, 'b');
DLinklistPushback(head, 'c'); 
DLinklistPushback(head, 'd');
Printchar(head, "先插四个元素"); 
DLinklistPopback(head); 
DLinklistPopback(head);
Printchar(head, "尾删两个元素"); 
DLinklistPopback(head);
DLinklistPopback(head);
Printchar(head, "再尾删两个元素"); 
DLinklistPopback(head); 
Printchar(head, "尝试对空链表尾删"); }
void TestPushfront()

FUNCTION(); DLinkNode* head;
DLinklistInit(&head); 
DLinklistPushfront(head, 'a');
DLinklistPushfront(head, 'b'); 
DLinklistPushfront(head, 'c');
DLinklistPushfront(head, 'd');
Printchar(head, "头插四个元素"); } 
void TestPopfront() { FUNCTION(); 
DLinkNode* head; DLinklistInit(&head);
DLinklistPushback(head, 'a'); 
DLinklistPushback(head, 'b'); 
DLinklistPushback(head, 'c'); 
DLinklistPushback(head, 'd');
Printchar(head, "尾插四个元素"); 
DLinklistPopfront(head);
DLinklistPopfront(head);
Printchar(head, "头删两个元素");
DLinklistPopfront(head);
DLinklistPopfront(head); 
Printchar(head, "再头删两个元素");
DLinklistPopfront(head);
DLinklistPopfront(head); 
Printchar(head, "尝试对空链表头删"); }
void TestFind() { FUNCTION(); 
DLinkNode* head; DLinklistInit(&head);
DLinklistPushback(head, 'a'); 
DLinklistPushback(head, 'b');
DLinklistPushback(head, 'c'); 
DLinklistPushback(head, 'd');
Printchar(head, "尾插四个元素"); 
DLinkNode* cur = DLinklistFind(head, 'c'); 
printf("元素c的位置:%p\n", cur);

void TestInsert() 
{ FUNCTION(); DLinkNode* head;
DLinklistInit(&head);
DLinklistPushback(head, 'a'); 
DLinklistPushback(head, 'b');
DLinklistPushback(head, 'c');
DLinklistPushback(head, 'd'); 
Printchar(head, "尾插四个元素"); 
DLinkNode* pos = (DLinklistFind(head, 'c'));
DLinklistInsert(head, pos, 'X');
Printchar(head, "C之前插入元素X");
} void TestInsertafter() 
{
FUNCTION(); 
DLinkNode* head;
DLinklistInit(&head);
DLinklistPushback(head, 'a');
DLinklistPushback(head, 'b');
DLinklistPushback(head, 'c'); 
DLinklistPushback(head, 'd');
Printchar(head, "尾插四个元素"); 
DLinkNode* pos = DLinklistFind(head, 'c');
 DLinklistInsertafter(head, pos, 'Y');
 Printchar(head, "C之后插入元素Y"); } void TestErase()
 {
FUNCTION(); DLinkNode* head;
DLinklistInit(&head);
DLinklistPushback(head, 'a');
DLinklistPushback(head, 'b'); 
DLinklistPushback(head, 'c');
DLinklistPushback(head, 'd');
Printchar(head, "尾插四个元素"); 
DLinkNode* pos = DLinklistFind(head, 'c');
DLinklistErase(head, pos);
Printchar(head, "删除元素c"); }
 void TestRemove() 
 {
FUNCTION(); 
 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() {
FUNCTION();
DLinkNode* head;
DLinklistInit(&head);
DLinklistRemoveall(head, 'a');
}

猜你喜欢

转载自blog.csdn.net/qq_40736410/article/details/80152008