C语言数据结构编程练习-双向带头循环链表的创销增删改查
还是采用多文件编程,这是头文件:
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
typedef int elementType;
typedef struct DLink_List //双向链表
{
struct DLink_List* pre;
elementType value;
struct DLink_List* next;
}DLink;
void fn4();
void print_menu1(void);
DLink* create_node();
DLink* init_list();
void print_list(DLink* sentry);
void head_insert(DLink* sentry, elementType val);
void tail_insert(DLink* sentry, elementType val);
void head_delete(DLink* sentry);
void tail_delete(DLink* sentry);
DLink* find_list(DLink* sentry, elementType find_val);
void middle_insert(DLink* temp, elementType val);
void middle_delete(DLink* temp);
void change_list(DLink* temp, elementType val);
void destroy_list(DLink** sentry);
这是函数文件 :
#include "04.h"
//创建双向带头循环链表,并进行创销,增删改查操作
void fn4()
{
int order = 0;
int val = 0;
int find_val = 0;
DLink* sentry = NULL;//sentry 哨兵
DLink* temp = NULL;//定义一个临时的元素
print_menu1();
while (1)
{
printf("请输入您的操作指令:");
scanf("%d", &order);
switch (order)
{
case 1:
//初始化 初始化双向链表的哨兵位
sentry = init_list();
break;
case 2:
//遍历
print_list(sentry);
break;
case 3:
//头插
printf("请输入头插的元素值:");
scanf("%d", &val);
head_insert(sentry,val);
break;
case 4:
//尾插
printf("请输入尾插的元素值:");
scanf("%d", &val);
tail_insert(sentry, val);
break;
case 5:
//头删
head_delete(sentry);
break;
case 6:
//尾删
tail_delete(sentry);
break;
case 7:
//查找
printf("请输入要查找的元素值:");
scanf("%d", &find_val);
temp = find_list(sentry, find_val);
if (temp == NULL)
{
printf("链表里没有改元素\n");
}
else
{
printf("链表里有改元素,值为:%d\n",temp->value);
}
break;
case 8:
//中间删
printf("请输入要删除的元素值:");
scanf("%d", &find_val);
temp = find_list(sentry, find_val);
if (temp == NULL)
{
printf("链表里没有该元素\n");
}
else
{
middle_delete(temp);
}
break;
case 9:
//中间插
printf("请输入要在哪个元素后面插入:");
scanf("%d", &find_val);
temp = find_list(sentry, find_val);
if (temp == NULL)
{
printf("链表里没有该元素\n");
}
else
{
printf("请输入要插入的元素值:");
scanf("%d", &val);
middle_insert(temp,val);
}
break;
case 10:
//修改
printf("请输入要修改的元素值:");
scanf("%d", &find_val);
temp = find_list(sentry, find_val);
if (temp == NULL)
{
printf("链表里没有该元素\n");
}
else
{
printf("请输入修改后的元素值:");
scanf("%d", &val);
change_list(temp,val);
}
break;
case 11:
//销毁
destroy_list(&sentry);
break;
case 12:
//退出
return;
default:
printf("指令有误重新输入\n");
}
}
}
//打印菜单
void print_menu1(void)
{
system("cls");//屏幕清空
printf("操作指令说明:\n");
printf("1:链表初始化\n2:打印链表\n");
printf("3:链表头插\n4:链表尾插\n");
printf("5:链表头删\n6:链表尾删\n");
printf("7:链表的查找\n8:链表的中间删\n");
printf("9:链表的中间插\n10:链表元素修改\n");
printf("11:链表链表销毁\n12:退出\n");
}
//辅助函数 创建新节点函数
DLink* create_node()
{
DLink* newnode = (DLink*)malloc(sizeof(DLink));
if (!newnode) exit(-1);
//初始化
memset(newnode, 0, sizeof(DLink));
return newnode;
}
//双向链表哨兵位初始化函数
DLink* init_list()
{
DLink* sentry = create_node(); //sentry:哨兵
//初始化哨兵位
sentry->next = sentry;
sentry->pre = sentry;
printf("双向链表初始化成功\n");
return sentry;
}
//打印双向链表
void print_list(DLink* sentry)
{
//判断有无初始化
assert(sentry);
DLink* temp = sentry->next;//保存头节点
//判空
if (temp == sentry)
{
printf("空表,无法打印\n");
return;
}
//遍历
while (temp!= sentry)
{
printf(" %d ", temp->value);
temp = temp->next;
}
printf("\n");
}
//双向链表头插
void head_insert(DLink* sentry,elementType val)
{
//定义一个新节点
DLink* newnode = create_node();
//新节点赋值
newnode->value = val;
//插入
newnode->next = sentry->next;
sentry->next->pre = newnode;
newnode->pre = sentry;
sentry->next = newnode;
printf("头插成功\n");
}
//双向链表尾插
void tail_insert(DLink* sentry, elementType val)
{
DLink* newnode = create_node();
newnode->value = val;
//尾插,需要找到尾节点 sentry->pre就是尾节点
/*DLink* temp = sentry->pre;//把尾节点定义一个临时节点
newnode->pre = temp;
newnode->next = sentry;
temp->next = newnode;
temp = newnode;*/
newnode->pre= sentry->pre;
sentry->pre->next = newnode;
newnode->next = sentry;
sentry->pre = newnode;
printf("尾插成功\n");
}
//双向链表头删
void head_delete(DLink* sentry)
{
DLink* temp = sentry->next;//保存头节点
sentry->next = temp->next;
temp->next->pre = sentry;
free(temp);
printf("双向链表头删成功\n");
}
//双向链表尾删
void tail_delete(DLink* sentry)
{
//定义一个临时变量保存尾节点
DLink* temp = sentry->pre;
sentry->pre = temp->pre;
temp->pre->next = sentry;
free(temp);
printf("双向链表尾删成功\n");
}
//双向链表查找元素
DLink* find_list(DLink* sentry, elementType find_val)
{
assert(sentry);
DLink* temp = sentry->next;//头节点
//遍历
while (temp != sentry)
{
if (temp->value == find_val)
{
return temp;
}
temp = temp->next;
}
return NULL;
}
//中间删
void middle_delete(DLink* temp)
{
temp->pre->next = temp->next;
temp->next->pre = temp->pre;
free(temp);
}
//双向链表中间插入
void middle_insert(DLink* temp, elementType val)
{
DLink* newnode = create_node();
newnode->value = val;
newnode->next = temp->next;
temp->next->pre = newnode;
newnode->next = newnode;
newnode->pre = temp;
printf("双向链表中间插入成功\n");
}
//元素修改
void change_list(DLink* temp, elementType val)
{
temp->value = val;
printf("修改成功\n");
}
//链表销毁
void destroy_list(DLink** sentry)
{
assert(*sentry);
while (*sentry)
{
DLink* temp = (*sentry)->next;
free(*sentry);
*sentry = temp;
}
//循环结束后把哨兵制空
*sentry = NULL;
printf("双向链表销毁成功\n");
}