当前位置: 首页 > article >正文

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");
}


http://www.kler.cn/a/507983.html

相关文章:

  • python——句柄
  • 指针的进阶
  • 关于vite+vue3+ts项目中env.d.ts 文件详解
  • RK3568平台(音频篇)lineout无声调试
  • 如何有效防止和解决IP劫持问题
  • 本地部署Web-Check网站检测与分析利器并实现远程访问实时监测
  • 关于在 Kotlin DSL 中,ndk 的配置方式
  • Windows重装后NI板卡LabVIEW恢复正常
  • Linux内核编程(二十一)USB应用及驱动开发
  • Leetcode3097:或值至少为 K 的最短子数组 II
  • C 语言运算符的优先级和结合性
  • 解答二重积分
  • 智能化量化模型的前沿探索:中阳的崛起
  • [BrainShadow-V1] VR头戴设备统计报告
  • 分布式系统、微服务、SOA初步理解
  • ubuntu设置代理服务器
  • “深入浅出”系列之设计模式篇:(0)什么是设计模式
  • Objective-C语言的数据类型
  • windows蓝牙驱动开发-BLE音频(一)
  • Linux测试处理fps为30、1920*1080、一分钟的视频性能
  • BGP边界网关协议(Border Gateway Protocol)概念、邻居建立
  • 【西藏乡镇界面】图层arcgis格式shp数据有乡镇名称和编码2020年wgs84坐标内容测评
  • C++/C语言判断重复数组(zznu)⭐
  • Java算法 二叉树入门 力扣简单题相同的树 翻转二叉树 判断对称二叉树 递归求二叉树的层数
  • 刷题记录 回溯算法-16:47. 全排列 II
  • 从玩具到工业控制--51单片机的跨界传奇【3】