题目名称:
双链表的增删查改
题目内容:
带头+双向+循环链表增删查改实现
第一步 创建三个文件
第二步 代码实现
1.List.c部分
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include <stdbool.h>
#include "List.h"
enum Option
{
退出链表,
头插,
头删,
尾插,
尾删,
随机插值,
删除数值,
查找数值,
打印链表
};
void menu()
{
printf("*****************************************\n");
printf("****** 1.头插 2.头删 ******\n");
printf("****** 3.尾插 4.尾删 ******\n");
printf("****** 5.随机插值 6.删除数值 ******\n");
printf("****** 7.查找数值 8.打印链表 ******\n");
printf("****** 0.退出链表 ******\n");
printf("*****************************************\n");
}
int main()
{
LN* pList = NULL;
ListInit(&pList);
int input = 0;
do
{
menu();
printf("请输入要进行的操作:");
scanf("%d", &input);
switch (input)
{
case (头插):
ListPushFrant(pList);
break;
case (头删):
ListPopFrant(pList);
break;
case (尾插):
ListPushBack(pList);
break;
case (尾删):
ListPopBack(pList);
break;
case (随机插值):
ListInsert(pList);
break;
case (删除数值):
ListErase(pList);
break;
case (查找数值):
ListFind(pList);
break;
case (打印链表):
ListPrint(pList);
break;
case (退出链表):
ListDestroy(pList);
break;
default:
printf("输入有误,请重新输入\n");
break;
}
} while (input);
return 0;
}
2.List.h部分
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include <stdbool.h>
//1.定义结构体
typedef struct ListNode
{
int data;
struct ListNode* next;
struct ListNode* prev;
}LN;
//2.获得新节点函数声明
LN* BuyLTNode(LN* pList);
//3.初始化结构体函数声明
void ListInit(LN** ppList);
//4.插入函数声明
void ListInsert(LN* pList);
//5.打印函数声明
void ListPrint(LN* pList);
//6.回收链表函数声明
void ListDestroy(LN* pList);
//7.头插函数声明
void ListPushFrant(LN* pList);
//8.头删函数声明
void ListPopFrant(LN* pList);
//9.尾插函数声明
void ListPushBack(LN* pList);
//10.尾删函数声明
void ListPopBack(LN* pList);
//11.删除节点函数声明
void ListErase(LN* pList);
//12.查找函数节点声明
void ListFind(LN* pList);
3.ListFunc.c部分
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include <stdbool.h>
#include "List.h"
//2.获得新节点函数实现
LN* BuyLTNode(int x)
{
LN* newnode = (LN*)malloc(sizeof(LN));
if (newnode == NULL)
{
printf("BuyLTNode::()%s\n", strerror(errno));
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
newnode->prev = NULL;
return newnode;
}
//3.初始化结构体函数实现
void ListInit(LN** ppList)
{
assert(ppList);
*ppList = BuyLTNode(0);
(*ppList)->next = *ppList;
(*ppList)->prev = *ppList;
}
//4.插入函数实现
void ListInsert(LN* pList)
{
assert(pList);
if (pList->next == pList)
{
printf("暂无节点,请输入数值进行插值:");
int x = 0;
scanf("%d", &x);
LN* newnode = BuyLTNode(x);
newnode->next = pList;
newnode->prev = pList;
pList->next = newnode;
pList->prev = newnode;
}
else
{
printf("请输入要在哪个数值前面插值:");
int y = 0;
scanf("%d", &y);
LN* cur = pList->next;
while (cur != pList)
{
if (cur->data == y)
{
break;
}
cur = cur->next;
}
if (cur == pList)
{
printf("无此节点,请重新输入:\n");
return;
}
printf("请输入要插入的值:");
int val = 0;
scanf("%d", &val);
LN* newnode = BuyLTNode(val);
newnode->prev = cur->prev; //与前节点连接
cur->prev->next = newnode;
newnode->next = cur; //与后节点连接
cur->prev = newnode;
}
printf("插入数值成功!\n");
}
//5.打印函数实现
void ListPrint(LN* pList)
{
assert(pList);
LN* cur = pList->next;
while (cur != pList)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}
//6.回收链表函数实现
void ListDestroy(LN* pList)
{
assert(pList);
LN* Cur = pList->next;
LN* CurNext = Cur->next;
while (Cur != pList)
{
CurNext = Cur->next; //先保存下一个节点
Cur->next = NULL;
Cur->prev = NULL;
free(Cur);
Cur = NULL;
Cur = CurNext;
}
pList->next = NULL;
pList->prev = NULL;
free(pList);
pList = NULL;
printf("回收空间成功,退出链表\n");
}
//7.头插函数实现
void ListPushFrant(LN* pList)
{
assert(pList);
printf("请输入要头插的数值:");
int x = 0;
scanf("%d", &x);
LN* newnode = BuyLTNode(x);
newnode->next = pList->next; //与后节点连接
pList->next->prev = newnode;
newnode->prev = pList; //与哨兵位连接
pList->next = newnode;
printf("头插函数成功!\n");
}
//8.头删函数实现
void ListPopFrant(LN* pList)
{
assert(pList);
if (pList->next == pList)
{
printf("无节点,无法头删\n");
return;
}
LN* pos = pList->next;
pList->next->next->prev = pList;
pList->next = pList->next->next;
pos->next = NULL;
pos->prev = NULL;
free(pos);
printf("头删成功!\n");
}
//9.尾插函数实现
void ListPushBack(LN* pList)
{
assert(pList);
printf("请输入要尾插的数值:");
int x = 0;
scanf("%d", &x);
LN* newnode = BuyLTNode(x);
newnode->prev = pList->prev;
pList->prev->next = newnode;
newnode->next = pList;
pList->prev = newnode;
printf("尾插成功!\n");
}
//10.尾删函数实现
void ListPopBack(LN* pList)
{
assert(pList);
if (pList->next == pList)
{
printf("无节点,无法尾删\n");
return;
}
LN* pos = pList->prev;
pList->prev->prev->next = pList;
pList->prev = pList->prev->prev;
pos->next = NULL;
pos->prev = NULL;
free(pos);
printf("尾删成功!\n");
}
//11.删除节点函数实现
void ListErase(LN* pList)
{
assert(pList);
if (pList->next == pList)
{
printf("无节点,无法删除\n");
return;
}
printf("请输入要删除的数值:");
int x = 0;
scanf("%d", &x);
LN* cur = pList->next;
while (cur != pList)
{
if (cur->data == x)
{
break;
}
cur = cur->next;
}
if (cur == pList)
{
printf("无该节点,无法删除\n");
return;
}
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
cur->next = NULL;
cur->prev = NULL;
free(cur);
printf("删除节点成功\n");
}
//12.查找函数节点实现
void ListFind(LN* pList)
{
assert(pList);
if (pList->next == pList)
{
printf("无节点,无法查找\n");
return;
}
printf("请输入要查找的数值:");
int x = 0;
scanf("%d", &x);
LN* cur = pList->next;
while (cur != pList)
{
if (cur->data == x)
{
break;
}
cur = cur->next;
}
if (cur == pList)
{
printf("无该节点\n");
return;
}
printf("数值%d的地址为%p\n", x, cur);
}