今天,我将带来带头双向循环链表的代码总结。
目录
带头双向循环链表的三个文档
List.h--------头文件的引用和函数的声明
List.c--------函数的定义
test.c--------带头双向循环链表的检验
初始化函数
//初始化的函数
SLNode* InitList()
{
SLNode* Head = (SLNode*)malloc(sizeof(SLNode));
if (Head == NULL)
{
perror("InitList()");
exit(1);
}
Head->next = Head;
Head->prev = Head;
Head->val = -1;
}
开辟结点的函数
//开辟结点的函数
SLNode* BuyListNode(SListType x)
{
SLNode* NewNode = (SLNode*)malloc(sizeof(SLNode));
if (NewNode == NULL)
{
perror("BuyListNode()");
exit(1);
}
NewNode->val = x;
NewNode->prev = NULL;
NewNode->next = NULL;
return NewNode;
}
打印函数
//打印函数
void Print(SLNode* Head)
{
assert(Head);
SLNode* cur = Head->next;
while (cur != Head)
{
printf("%d ",cur->val);
cur = cur->next;
}
printf("\n");
}
销毁链表的函数
//销毁链表的函数
void DestroyList(SLNode* Head)
{
assert(Head);
SLNode* cur = Head->next;
while (cur != Head)
{
SLNode* Next = cur->next;
free(cur);
cur = Next;
}
free(cur);
}
统计结点个数的函数
//统计结点的个数
size_t LTsize(SLNode* Head)
{
assert(Head);
size_t count = 0;
SLNode* cur = Head->next;
while (cur != Head)
{
count++;
cur = cur->next;
}
return count;
}
检验链表是否为空的函数
//检验链表是否为空
bool LTEmpty(SLNode* Head)
{
assert(Head);
return Head->next == Head;
}
在pos位置插入数据的函数
//在pos位置前插入
void SLInsert(SLNode* pos, SListType x)
{
assert(pos);
SLNode* NewNode = BuyListNode(x);
SLNode* Prev = pos->prev;
Prev->next = NewNode;
pos->prev = NewNode;
NewNode->prev = Prev;
NewNode->next = pos;
}
删除pos位置数据的函数
//删除pos位置的数据
void SLErase(SLNode* pos)
{
assert(pos);
SLNode* Prev = pos->prev;
SLNode* Next = pos->next;
free(pos);
Prev->next = Next;
Next->prev = Prev;
}
头插和头删函数
//头插
void SLPushFront(SLNode* Head, SListType x)
{
assert(Head);
SLInsert(Head->next,x);
}
//头删
void SLPopFront(SLNode* Head)
{
assert(Head);
assert(Head->next != Head);
SLErase(Head->next);
}
尾插和尾删函数
//尾插
void SLPushBack(SLNode* Head, SListType x)
{
assert(Head);
SLInsert(Head,x);
}
//尾删
void SLPopBack(SLNode* Head)
{
assert(Head);
assert(Head->prev != Head);
SLErase(Head->prev);
}
查找函数
//查找函数
SLNode* Find(SLNode* Head, SListType x)
{
assert(Head);
SLNode* cur = Head->next;
while (cur != Head)
{
if (cur->val == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
菜单的实现和函数的调用
void menu()
{
printf("**************************************************\n");
printf("***** 1.头插 2.头删 *****\n");
printf("***** 3.尾插 4.尾删 *****\n");
printf("***** 5.pos前插入 6.删除pos位置数据 *****\n");
printf("***** 7.统计结点的个数 8.检验链表是否为空 *****\n");
printf("***** 9.打印函数 10.查找 *****\n");
printf("***** 0.退出 *****\n");
printf("**************************************************\n");
}
int main()
{
int input = 0;
int num = 0;
int Pos = 0;
SLNode* Head = InitList();
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
printf("请输入你要插入的数据\n");
scanf("%d", &num);
SLPushFront(Head, num);
break;
case 2:
SLPopFront(Head);
break;
case 3:
printf("请输入你要插入的数据\n");
scanf("%d", &num);
SLPushBack(Head, num);
break;
case 4:
SLPopBack(Head);
break;
case 5:
printf("请输入你要在哪个数字前插入\n");
scanf("%d", &Pos);
printf("请输入你要插入的数据\n");
scanf("%d", &num);
SLNode* pos = Find(Head, Pos);
SLInsert(pos, num);
break;
case 6:
printf("请输入你要删除哪个数据\n");
scanf("%d", &Pos);
pos = Find(Head, Pos);
SLErase(pos);
break;
case 7:
printf("%d\n", LTsize(Head));
break;
case 8:
if (LTEmpty(Head) == true)
printf("链表为空\n");
else
printf("链表非空\n");
break;
case 9:
Print(Head);
break;
case 10:
printf("请输入你要查找的数据\n");
scanf("%d", &num);
pos = Find(Head, num);
if (pos == NULL)
printf("找不到\n");
else if (pos->prev == Head)
printf("头结点\n");
else if (pos->next == Head)
printf("尾结点\n");
else
printf("地址是:%x,在数字:%d的后面,%d的前面\n", pos, pos->prev->val, pos->next->val);
break;
case 0:
printf("退出\n");
DestroyList(Head);
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
函数的声明
//初始化的函数
SLNode* InitList();
//开辟结点的函数
SLNode* BuyListNode(SListType x);
//打印函数
void Print(SLNode* Head);
//销毁链表的函数
void DestroyList(SLNode* Head);
//统计结点的个数
size_t LTsize(SLNode* Head);
//检验链表是否为空
bool LTEmpty(SLNode* Head);
//在pos位置前插入
void SLInsert(SLNode* pos, SListType x);
//删除pos位置的数据
void SLErase(SLNode* pos);
//头插
void SLPushFront(SLNode* Head, SListType x);
//头删
void SLPopFront(SLNode* Head);
//尾插
void SLPushBack(SLNode* Head, SListType x);
//尾删
void SLPopBack(SLNode* Head);
//查找函数
SLNode* Find(SLNode* Head, SListType x);
List.c文档的代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "List.h"
//初始化的函数
SLNode* InitList()
{
SLNode* Head = (SLNode*)malloc(sizeof(SLNode));
if (Head == NULL)
{
perror("InitList()");
exit(1);
}
Head->next = Head;
Head->prev = Head;
Head->val = -1;
}
//开辟结点的函数
SLNode* BuyListNode(SListType x)
{
SLNode* NewNode = (SLNode*)malloc(sizeof(SLNode));
if (NewNode == NULL)
{
perror("BuyListNode()");
exit(1);
}
NewNode->val = x;
NewNode->prev = NULL;
NewNode->next = NULL;
return NewNode;
}
//打印函数
void Print(SLNode* Head)
{
assert(Head);
SLNode* cur = Head->next;
while (cur != Head)
{
printf("%d ",cur->val);
cur = cur->next;
}
printf("\n");
}
//销毁链表的函数
void DestroyList(SLNode* Head)
{
assert(Head);
SLNode* cur = Head->next;
while (cur != Head)
{
SLNode* Next = cur->next;
free(cur);
cur = Next;
}
free(cur);
}
//统计结点的个数
size_t LTsize(SLNode* Head)
{
assert(Head);
size_t count = 0;
SLNode* cur = Head->next;
while (cur != Head)
{
count++;
cur = cur->next;
}
return count;
}
//检验链表是否为空
bool LTEmpty(SLNode* Head)
{
assert(Head);
return Head->next == Head;
}
//在pos位置前插入
void SLInsert(SLNode* pos, SListType x)
{
assert(pos);
SLNode* NewNode = BuyListNode(x);
SLNode* Prev = pos->prev;
Prev->next = NewNode;
pos->prev = NewNode;
NewNode->prev = Prev;
NewNode->next = pos;
}
//删除pos位置的数据
void SLErase(SLNode* pos)
{
assert(pos);
SLNode* Prev = pos->prev;
SLNode* Next = pos->next;
free(pos);
Prev->next = Next;
Next->prev = Prev;
}
//头插
void SLPushFront(SLNode* Head, SListType x)
{
assert(Head);
SLInsert(Head->next,x);
}
//头删
void SLPopFront(SLNode* Head)
{
assert(Head);
assert(Head->next != Head);
SLErase(Head->next);
}
//尾插
void SLPushBack(SLNode* Head, SListType x)
{
assert(Head);
SLInsert(Head,x);
}
//尾删
void SLPopBack(SLNode* Head)
{
assert(Head);
assert(Head->prev != Head);
SLErase(Head->prev);
}
//查找函数
SLNode* Find(SLNode* Head, SListType x)
{
assert(Head);
SLNode* cur = Head->next;
while (cur != Head)
{
if (cur->val == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
List.h文档的代码
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int SListType;
typedef struct ListNode
{
SListType val;
struct ListNode* prev;
struct ListNode* next;
}SLNode;
//初始化的函数
SLNode* InitList();
//开辟结点的函数
SLNode* BuyListNode(SListType x);
//打印函数
void Print(SLNode* Head);
//销毁链表的函数
void DestroyList(SLNode* Head);
//统计结点的个数
size_t LTsize(SLNode* Head);
//检验链表是否为空
bool LTEmpty(SLNode* Head);
//在pos位置前插入
void SLInsert(SLNode* pos, SListType x);
//删除pos位置的数据
void SLErase(SLNode* pos);
//头插
void SLPushFront(SLNode* Head, SListType x);
//头删
void SLPopFront(SLNode* Head);
//尾插
void SLPushBack(SLNode* Head, SListType x);
//尾删
void SLPopBack(SLNode* Head);
//查找函数
SLNode* Find(SLNode* Head, SListType x);
test.c文档的代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "List.h"
void menu()
{
printf("**************************************************\n");
printf("***** 1.头插 2.头删 *****\n");
printf("***** 3.尾插 4.尾删 *****\n");
printf("***** 5.pos前插入 6.删除pos位置数据 *****\n");
printf("***** 7.统计结点的个数 8.检验链表是否为空 *****\n");
printf("***** 9.打印函数 10.查找 *****\n");
printf("***** 0.退出 *****\n");
printf("**************************************************\n");
}
int main()
{
int input = 0;
int num = 0;
int Pos = 0;
SLNode* Head = InitList();
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
printf("请输入你要插入的数据\n");
scanf("%d", &num);
SLPushFront(Head, num);
break;
case 2:
SLPopFront(Head);
break;
case 3:
printf("请输入你要插入的数据\n");
scanf("%d", &num);
SLPushBack(Head, num);
break;
case 4:
SLPopBack(Head);
break;
case 5:
printf("请输入你要在哪个数字前插入\n");
scanf("%d", &Pos);
printf("请输入你要插入的数据\n");
scanf("%d", &num);
SLNode* pos = Find(Head, Pos);
SLInsert(pos, num);
break;
case 6:
printf("请输入你要删除哪个数据\n");
scanf("%d", &Pos);
pos = Find(Head, Pos);
SLErase(pos);
break;
case 7:
printf("%d\n", LTsize(Head));
break;
case 8:
if (LTEmpty(Head) == true)
printf("链表为空\n");
else
printf("链表非空\n");
break;
case 9:
Print(Head);
break;
case 10:
printf("请输入你要查找的数据\n");
scanf("%d", &num);
pos = Find(Head, num);
if (pos == NULL)
printf("找不到\n");
else if (pos->prev == Head)
printf("头结点\n");
else if (pos->next == Head)
printf("尾结点\n");
else
printf("地址是:%x,在数字:%d的后面,%d的前面\n", pos, pos->prev->val, pos->next->val);
break;
case 0:
printf("退出\n");
DestroyList(Head);
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
今天的带头双向循环链表的代码总结就到这里,关注点一点,下期更精彩。