【Day4】数据结构单链表

思维导图:
在这里插入图片描述
main.c:

#include "head.h"
void menue()
{
	
	puts("****************");
	puts("\t1,单项链表头插");
	puts("\t2,单项链表遍历");
	puts("\t3,单项链表尾插");
	puts("\t4,单向链表头删");
	puts("\t5,单向链表尾删");
	puts("\t6,单向链表按下表插入");
	puts("\t7,单向链表按下表删除");
	puts("\t8,单向链表按下表修改");
	puts("\t9,单向链表按下表查找");
	puts("\t10,单链表按元素查找");
	puts("\t11,单链表按元素插入");
	puts("\t12,单链表按元素删除");
	puts("\t13,单链表按元素修改");
	puts("\t14,单链表排序");
	puts("\t15,单链表逆置");
	puts("\t16,单链表释放空间");
	puts("\t0,结束程序");
	puts("****************");
}
int main(int argc, const char *argv[])
{
	menue();
	int number;
	linklist L = create(1);
	while(1)
	{
		printf("\n请输入您的选择:");
		scanf("%d",&number);
		switch(number)
		{
		case 1:{
				   datatype e;
				   printf("请输入你要插入的数据:");
				   scanf("%d",&e);
				   insert_head(L,e);
			   }break;
		case 2:{
				   output(L);
			   }break;
		case 3:{
				   datatype e;
				   printf("请输入你要插入的数据:");
				   scanf("%d",&e);
				   insert_rear(L,e);
			   }break;
		case 4:{
				   delete_head(L);
			   }break;
		case 5:{
				   delete_rear(L);
			   }break;
		case 6:{
				   int n;
				   datatype e;
				   printf("请输入你要插入的数据:");
				   scanf("%d",&e);
				   printf("请输入你要插入的位置:");
				   scanf("%d",&n);
				   insert_sub(L,n,e);
			   }break;
		case 7:{
				   int n;
				   datatype e;
				   printf("请输入你要删除的数据位置:");
				   scanf("%d",&n);		  
				   delete_sub(L,n);
			   }break;
		case 8:{
				   int n;
				   datatype e;
				   printf("请输入你要修改的数据位置:");
				   scanf("%d",&n);
				   printf("请输入你要修改的值:");
				   scanf("%d",&e);
				   updata_sub(L,n,e);
			   }break;
		case 9:{
				   int n;
				   printf("请输入你要查找的数据位置:");
				   scanf("%d",&n);
				   find_sub(L,n);
			   }break;
		case 10:{
					datatype e;
					printf("请输入查找的元素:");
					scanf("%d",&e);
					find_data(L,e);
				}break;
		case 11:{
					datatype e;
					printf("请输入插入位置的元素:");
					scanf("%d",&e);
					insert_data(L,e);
				}break;
		case 12:{
					datatype e;
					printf("请输入删除位置的元素:");
					scanf("%d",&e);
					delete_data(L,e);
				}break;
		case 13:{
					datatype e,new;
					printf("请输入修改位置的元素:");
					scanf("%d",&e);
					printf("请输入修改的的元素:");
					scanf("%d",&new);
					updata_data(L,e,new);
				}break;
		case 14:{
					bubble(L);	
				}break;
		case 15:{
					reverse(L);
				}break;
		case 16:{
					L = free_space(L);
					L = NULL;
				}break;
		default:printf("输入错误,请重新输入\n");break;
		case 0:printf("退出程序\n");exit(0);
		}
	}
	return 0;
}

head.h

#ifndef Head_H
#define Head_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int datatype;
typedef struct Node
{
	//数据域
	union{
		int len;//头结点的数据域
		datatype data;//其他结点的数据域
	};
	//指针域
	struct Node *next;
}*linklist;

linklist create(int flag);
int insert_head(linklist L,datatype e);
int insert_rear(linklist L,datatype e);
void output(linklist L);
int delete_head(linklist L);
int delete_rear(linklist L);
int insert_sub(linklist L,int n,datatype e);
int delete_sub(linklist L,int n);
int updata_sub(linklist L,int n,datatype e);
int find_sub(linklist L,int n);
int find_data(linklist L,datatype e);
int insert_data(linklist L,datatype e);
int delete_data(linklist L,datatype e);
int updata_data(linklist L,datatype e,datatype new);
void bubble(linklist L);
int reverse(linklist L);
linklist free_space(linklist L);
#endif

test.c

#include "head.h"
/*
 * function:    创建结点
 * @param [ in] 
 * @param [out] 
 * @return      成功返回地址 失败返回NULL
 */
linklist create(int flag)
{
	//创建结点
	linklist L = (linklist)malloc(sizeof(struct Node));
	//创建失败
	if(L==NULL)
		return NULL;
	//对头结点初始化
	if(flag==1)
		L->len = 0;
	//普通结点
	else if(flag==0)
		L->data = 0;
	//对结点的指针进行初始化
	L->next = NULL;
	return L;
}
/*
 * function:    头插
 * @param [ in] 链表 插入的值
 * @param [out] 
 * @return      成功返回0,失败返回-1
 */
int insert_head(linklist L,datatype e)
{
	//判断链表是否创建
	if(L==NULL){
		printf("头插失败\n");
		return -1;
	}
	//头插
	//创建新结点s
	linklist s = create(0);
	if(s==NULL){
		printf("头插失败\n");
		return-1;
	}
	//s的数据域赋值
	s->data = e;
	//连接s进单链表
	s->next = L->next;
	L->next = s;
	//单链表长度增加
	L->len++;
	return 0;
}
/*
 * function:    单链表的尾插
 * @param [ in] 单链表 插入的值
 * @param [out] 
 * @return      成功返回0,失败返回-1
 */
int insert_rear(linklist L,datatype e)
{
	//判断单链表是否创建
	if(L==NULL){
		printf("尾插失败\n");
		return -1;
	}
	//循环到尾结点
	linklist p = L;
	while(p->next!=NULL)
		p = p->next;
	//在最后一个结点前面插入s
	linklist s = create(0);
	if(s==NULL){
		printf("尾插失败\n");
		return -1;
	}
	//数据域赋值
	s->data = e;
	//连接s
	p->next = s;
	L->len++;
	return 0;
}
/*
 * function:    单链表的遍历
 * @param [ in] 单链表
 * @param [out] 
 * @return      无
 */
void output(linklist L)
{
	//判断单链表是否创建
	//判断单链表是否为空
	if(L==NULL||L->len==0)
		printf("遍历失败\n");
	//遍历
	linklist p = L;
	for(int i = 0;i<L->len;i++){
		p=p->next;//后移
		printf("%d\t",p->data);
	}
	puts("");
}
/*
 * function:    单链表的头删
 * @param [ in] 单链表
 * @param [out] 
 * @return      成功返回0,失败返回-1
 */
int delete_head(linklist L)
{
	//判断单链表是否创建
	//判断单链表是否为空
	if(L==NULL||L->len==0){
		printf("删除失败\n");
		return -1;
	}
	linklist q = L->next;
	L->next = q->next;
	free(q);
	q = NULL;
	L->len--;
	return 0;
}
/*
 * function:    单链表的尾删
 * @param [ in] 单链表
 * @param [out] 
 * @return      成功返回0,失败返回-1
 */
int delete_rear(linklist L)
{
	//判断单链表是否创建
	//判断单链表是否为空
	if(L==NULL||L->len==0){
		printf("删除失败\n");
		return -1;
	}
	linklist p = L;
	//循环到倒数第二个
	while(p->next->next!=NULL)
		p = p->next;
	linklist q = p->next;
	p->next = NULL;
	free(q);
	q = NULL;
	L->len--;
	return 0;
}
/*
 * function:   按下标插入 
 * @param [ in] 单链表 插入位置 插入的值
 * @param [out] 
 * @return      成功返回0,失败返回-1
 */
int insert_sub(linklist L,int n,datatype e)
{
	//判断单链表是否创建
	//判断位置是否合法
	if(L==NULL||n<1||n>L->len+1){
		printf("插入失败\n");
		return -1;
	}
	//循环到插入位置的前一个
	linklist p = L;
	for(int i = 0;i<n-1;i++){
		p = p->next;
	}
	//创建新结点
	linklist s = create(0);
	if(s==NULL)
		return -1;
	//s的数据域赋值
	s->data = e;
	//连接s
	s->next = p->next;
	p->next = s;
	L->len++;
	return 0;
}
/*
 * function:    单链表按位置删除
 * @param [ in] 单链表 位置 
 * @param [out] 
 * @return      成功返回0,失败返回-1
 */
int delete_sub(linklist L,int n)
{
	//判断单链表是否创建
	//判断单链表是否为空
	//判断位置是否合法
	if(L==NULL||L->len==0||n<1||n>L->len){
		printf("删除失败\n");
		return -1;
	}
	//循环到删除位置的前一个,用p指向
	linklist p = L;
	for(int i = 0;i<n-1;i++){
		p = p->next;
	}
	//用q指向删除位置
	linklist q = p->next;
	//从单链表取出q
	p->next = q->next;
	free(q);
	q = NULL;
	L->len--;
	return 0;
}
/*
 * function:    单链表按位置修改
 * @param [ in] 单链表 位置 修改的值
 * @param [out] 
 * @return      成功返回0,失败返回-1
 */
int updata_sub(linklist L,int n,datatype e)
{
	//判断单链表是否创建
	//判断单链表是否为空
	//判断位置是否合法
	if(L==NULL||L->len==0||n<1||n>L->len){
		printf("修改失败\n");
		return -1;
	}
	//循环到修改位置,用p指向
	linklist p = L;
	for(int i = 0;i<n;i++)
		p = p->next;
	//修改p的数据域
	p->data = e;
	return 0;
}
/*
 * function:    单链表按位置查找
 * @param [ in] 单链表 位置
 * @param [out] 
 * @return      成功返回0,失败返回-1
 */
int find_sub(linklist L,int n)
{
	//判断单链表是否创建
	//判断单链表是否为空
	//判断位置是否合法
	if(L==NULL||L->len==0||n<1||n>L->len){
		printf("查找失败\n");
		return -1;
	}
	//循环到查找位置,用p指向
	linklist p = L;
	for(int i = 0;i<n;i++){
		p = p->next;
	}
	printf("查找的值是:%d\n",p->data);
	return 0;
}
/*
 * function:    单链表的按元素查找
 * @param [ in] 链表 查找的值
 * @param [out] 
 * @return      成功返回位置,失败返回-1
 */
int find_data(linklist L,datatype e)
{
	//判断单链表是否创建
	//判断单链表是否为空
	if(L==NULL||L->len==0){
		printf("查找失败\n");
		return -1;
	}
	int sub = 0;
	linklist p = L;
	while(p->next!=NULL){
		p = p->next;
		sub++;
		if(p->data==e){
			return sub;
		}
	}
	return -1;
}
/*
 * function:    单链表的按元素插入
 * @param [ in] 单链表 插入位置元素的值
 * @param [out] 
 * @return      成功返回0,失败返回-1
 */
int insert_data(linklist L,datatype e)
{
	//根据e查找位置
	int sub = find_data(L,e);
	if(sub==-1)
		return -1;
	insert_sub(L,sub,e);
	return 0;
}
/*
 * function:    单链表的按元素删除
 * @param [ in] 单链表 删除位置元素的值
 * @param [out] 
 * @return      成功返回0,失败返回-1
 */
int delete_data(linklist L,datatype e)
{
	//根据e查找位置
	int sub = find_data(L,e);
	if(sub==-1)
		return -1;
	delete_sub(L,sub);
	return 0;
}
/*
 * function:    单链表的按元素修改
 * @param [ in] 单链表 修改前元素的值 修改后元素的值
 * @param [out] 
 * @return      成功返回0,失败返回-1
 */
int updata_data(linklist L,datatype e,datatype new)
{
	//根据e查找位置
	int sub = find_data(L,e);
	if(sub==-1)
		return -1;
	updata_sub(L,sub,new);
	return 0;
}
/*
 * function:    冒泡排序
 * @param [ in] 链表
 * @param [out]
 * @return      无
 */
void bubble(linklist L)
{
	//1,判断链表是否创建
	//2,判断链表是否为空
	if(L==NULL || L->next==NULL)
	{
		printf("排序失败\n");
	}
	//3,冒泡排序
	for(linklist i=L->next;i->next!=NULL;i=i->next)
	{
		int count=0;
		for(linklist j=L->next;j->next!=NULL;j=j->next)
		{
			if(j->data>j->next->data)
			{
				datatype t=j->data;
				j->data=j->next->data;
				j->next->data=t;
				count++;
			}
		}
		if(count==0)
			break;
	}
}
/*
 * function:    单链表的逆置
 * @param [ in] 单链表
 * @param [out] 
 * @return     成功返回0,失败返回-1 
 */
int reverse(linklist L)
{
	//判断单链表是否创建
	//判断单链表是否为空
	if(L==NULL||L->len==0)
		return -1;
	//工作指针p从头结点后一个元素开始指向
	linklist p = L->next;
	//断开头节点
	L->next = NULL;
	while(p!=NULL){
		//工作指针t指向p,p向后移动
		linklist t = p;
		p = p->next;
		//头插t
		t->next = L->next;
		L->next = t;
	}
	return 0;
}
/*
 * function:    单链表释放空间
 * @param [ in] 单链表
 * @param [out] 
 * @return 		返回L
 */
linklist free_space(linklist L)
{
	if(L==NULL)
		return NULL;
	int n = L->len;
	for(int i = 0;i<n;i++)
		delete_head(L);
	free(L);
	L = NULL;
	return L;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值