1201作业

思维导图

作业

头函数

复制代码
#include <myhead.h>
#include"linklist.h"
int main(int argc, const char *argv[])
{
	//调用创建链表函数
	node_ptr L = list_create();
	if(NULL == L)
	{
		return -1;
	}

	//调用头插函数
	list_insert_head(L,'Q');
	list_insert_head(L,'W');
	list_insert_head(L,'R');
	list_insert_head(L,'R');
	list_insert_head(L,'E');
	list_insert_head(L,'R');
	list_insert_head(L,'R');
	list_insert_head(L,'R');
	
	//展示
	list_show(L);

	//调用任意位置插入函数
	list_insert_pos(L,1,'D');
	list_insert_pos(L,2,'F');
	list_insert_pos(L,L->len+1,'F');
	list_show(L);

	//调用单链表尾插函数
	list_insert_trail(L,'x');
	list_show(L);


	//单链表头删
	list_delete_head(L);
	list_show(L);

	//单链表任意位置删除
	list_delete_pos(L,1);
	//list_delete_pos(L,3);
	//list_delete_pos(L,L->len);
	list_show(L);

	//调用单链表尾删函数
	list_delete_trail(L);
	list_show(L);

	//调用值查找数据位置函数
	printf("该值的位置在第%d节点\n",list_update_key(L,'E'));

	//调用位置修改函数
	list_update_pos(L,2,'H');
	list_show(L);

	//调用按值修改函数
	list_update_num(L,'H','B');
	list_show(L);

	//调用反转函数
	list_reverse(L);
	list_show(L);

	//调转排序函数
	list_sort(L);
	list_show(L);

	//调用去重函数
	list_remove(L);
	list_show(L);
	printf("该单链表的长度为:%d\n",list_long(L));

	//调用清空函数
	list_all_empty(L);
	list_show(L);

	//调用长度函数
	printf("该单链表的长度为:%d\n",list_long(L));


	//调用销毁函数
	list_destroy(L);
	L=NULL;
	list_show(L);


	return 0;
}

源代码

复制代码
#include"linklist.h"

//创建链表
node_ptr list_create()
{
	//在堆区申请一个头结点的空间
	node_ptr L = (node_ptr)malloc(sizeof(Node));
	if(NULL==L)
	{
		printf("链表创建失败\n");
		return NULL;
	}

	//程序执行至此,一个头节点申请成功
	//有了头结点,就有了一条链表
	//初始化操作
	L->len = 0;   //表示链表长度为0
	L->next = NULL; //防止野指针

	printf("链表创建成功\n");
	return L;
}

//链表判空操作
//如果链表为空,返回1,非空返回0
int list_empty(node_ptr L)
{
	//判断逻辑
	if(NULL==L)
	{
		printf("链表不合法\n");
		return -1;
	}

	return L->next==NULL?1:0;

}

//定义申请节点封装数据函数
node_ptr node_apply(datatype e)
{
	//在堆区申请一个节点的空间
	node_ptr p = (node_ptr)malloc(sizeof(Node));
	if(NULL==p)
	{
		printf("节点申请失败\n");
		return NULL;
	}

	//将数据封装进节点的数据域
	p->data = e;
	p->next = NULL;   //防止野指针

	return p;   //将封装好的节点地址返回
}

//单向链表头插
int list_insert_head(node_ptr L,datatype e)
{
	//判断逻辑
	if(NULL==L)
	{
		printf("链表不合法\n");
		return -1;
	}
	
	//申请节点封装数据
	node_ptr p = node_apply(e);
	if(NULL==p)
	{
		return -1;
	}
	//程序执行至此,表示节点申请成功,e已经封装进节点中
	//头插逻辑
	p->next = L->next;
	L->next = p;

	//表长变化
	L->len++;
	printf("插入成功\n");
	return 0;
}

//单向链表的按位置查找返回节点
node_ptr list_find_node(node_ptr L,int pos)
{
	//判断逻辑
	if(NULL==L || pos<0 || pos>L->len)
	{
		printf("查找失败\n");
		return NULL;
	}

	//查找逻辑
	node_ptr q = L;//定义遍历指针,从头结点出发
	for(int i=0;i<pos;i++)
	{
		q = q->next;  //将指针偏移到下一个节点位置
	}
	
	//返回节点
	return q;
}

//单向链表的遍历
int list_show(node_ptr L)
{
	//判断逻辑
	if(list_empty(L))
	{
		printf("遍历失败\n");
		return -1;
	}

	//展示逻辑
	printf("链表中的元素分别是:\n");
	node_ptr q = L->next;
	/*
	node_ptr q = L;
	for(int i=0;i<L->len;i++)
	{
		q = q->next;
		printf("%c\t",q->data);
	}
	*/

	while(q)
	{
		//当前节点不为空,输出数据域
		printf("%c\t",q->data);
		q = q->next;
	}
	putchar(10);
}

//单向链表任意位置插入
int list_insert_pos(node_ptr L,int pos,datatype e)
{
	//判断逻辑
	if(NULL==L || pos<1 || pos>L->len+1)
	{
		printf("插入失败\n");
		return -1;
	}

	//找到要插入位置的前一个节点
	node_ptr q = list_find_node(L,pos-1);

	//申请节点封装数据
	node_ptr p = node_apply(e);
	if(NULL==p)
	{
		return -1;
	}
	
	//插入逻辑
	p->next = q->next;
	q->next = p;

	//表长变化
	L->len++;
	printf("插入成功\n");
	return 0;
	
}

//单向链表的尾插
int list_insert_trail(node_ptr L,datatype e)
{
	//判断逻辑
	if(list_empty(L) || NULL==L)
	{
		printf("插入失败\n");
		return -1;
	}

	//申请新节点
	node_ptr p = node_apply(e);
	if(NULL==p)
	{
		return -1;
	}

	//插入逻辑
	node_ptr q = L;
	for(int i=0;i<L->len;i++)
	{
		q = q->next;
	}
	q->next = p;
	p->next = NULL;

	//表长变化
	L->len++;
	printf("插入成功\n");
	return 0;
}

//单链表头删
int list_delete_head(node_ptr L)
{
	//判断逻辑
	if(list_empty(L) || NULL==L)
	{
		printf("删除失败\n");
		return -1;
	}
	
	//删除逻辑
	node_ptr q = L->next;
	L->next = q->next;
	free(q);
	q = NULL;

	//表长变化
	L->len--;
	printf("删除成功\n");
	return 0;
}

//单向链表任意位置删除
int list_delete_pos(node_ptr L,int pos)
{
	//判断逻辑
	if(NULL==L || pos<1 || pos>L->len || list_empty(L))
	{
		printf("删除失败\n");
		return -1;
	}

	//找到删除位置的前一个节点
	node_ptr q = list_find_node(L,pos-1);

	//删除逻辑
	node_ptr p = q->next;
	q->next = p->next;
	free(p);
	p=NULL;

	//表长变化
	L->len--;
	printf("删除成功\n");
	return 0;
}

//单向链表的尾删
int list_delete_trail(node_ptr L)
{
	//判断逻辑
	if(list_empty(L) || NULL==L)
	{
		printf("删除失败\n");
		return -1;
	}

	//找到尾节点的前一节点
	node_ptr p = list_find_node(L,L->len-1);

	//删除逻辑
	p->next=NULL;
	free(p->next);
	p->next = NULL;

	//链表变化
	L->len--;
	printf("删除成功\n");
	return 0;
}

//单向链表按值查找返回位置
int list_update_key(node_ptr L,datatype e)
{
	//判断逻辑
	if(list_empty(L) || NULL==L)
	{
		return -1;
	}

	//查找逻辑
	node_ptr p = L;
	for(int i=0;i<L->len;i++)
	{
		p = p->next;
		if(p->data==e)
		{
			printf("查询成功\n");
			return i+1;
		}

	}
	printf("未查询到此值\n");
	return -1;
}

//单向链表按位置进行修改
int list_update_pos(node_ptr L,int pos,datatype e)
{
	//判断逻辑
	if(NULL==L || list_empty(L) || pos<1 || pos>L->len)
	{
		printf("修改失败\n");
		return -1;
	}

	//查找指定节点
	node_ptr p = list_find_node(L,pos);

	//进行修改
	p->data = e;

	printf("修改成功\n");
	return 0;
}

//单向链表按值进行修改
int list_update_num(node_ptr L,datatype old_e,datatype new_e)
{
	//判断逻辑
	if(NULL==L || list_empty(L))
	{
		printf("修改失败\n");
		return -1;
	}

	//查找指定的值
	node_ptr p = L;
	for(int i=0;i<L->len;i++)
	{
		p = p->next;
		if(p->data==old_e)
		{
			printf("查询成功\n");
			p->data = new_e;
			printf("修改成功\n");
			return 0;
		}
	}
	printf("修改失败\n");
	return -1;
}

//单向链表的反转
int list_reverse(node_ptr L)
{
	//判断逻辑
	if(NULL==L || list_empty(L) || L->len==1)
	{
		printf("反转失败\n");
		return -1;
	}

	//反转逻辑
	node_ptr H = L->next;
	L->next = NULL;

	while(H!=NULL)
	{
		node_ptr p = H;
		H = H->next;

		p->next = L->next;
		L->next = p;
	}

	printf("反转成功\n");
	return 0;
}

//单向链表的排序
int list_sort(node_ptr L)
{
	//判断逻辑
	if(list_empty(L) || NULL==L)
	{
		printf("排序失败\n");
		return -1;
	}

	//排序逻辑
	for(int i=1;i<L->len;i++)
	{
		node_ptr p = L->next;
		for(int j=0;j<L->len-i;j++)
		{
			if(p->data > p->next->data)
			{
				datatype t = p->next->data;
				p->next->data = p->next->next->data;
				p->next->next->data = t;
			}
			p = p->next;
		}
	}
	printf("排序成功\n");
	return 0;
}

//单向链表的去重
int list_remove(node_ptr L)
{
	//判断逻辑
	if(list_empty(L) || NULL==L)
	{
		printf("去重失败\n");
		return -1;
	}

	//去重逻辑
	node_ptr p = L->next;
	while(p!=NULL)
	{
		node_ptr q = p;
		node_ptr t = p;
		while(q->next!=NULL)
		{
			if(p->data == q->next->data)
			{
				node_ptr t = q->next;
				q->next = q->next->next;
				free(t);
				t=NULL;
				L->len--;
			}
			else
			{
				q= q->next;
			}
		}
		p = p->next;

	}
	printf("去重成功\n");
	return 0;
}

//单向链表的清空
int list_all_empty(node_ptr L)
{
	//判断逻辑
	if(NULL==L)
	{
		return -1;
	}

	//清空逻辑
	while(L->next!=NULL)
	{
		node_ptr p = L->next;
		L->next = p->next;
		free(p);
		p=NULL;
		L->len--;
	}

	printf("清空成功\n");
	return 0;

}

//返回单向链表的长度
int list_long(node_ptr L)
{
	//判断逻辑
	if(NULL==L)
	{
		return -1;
	}
	return L->len;
}

//单向链表的释放
void list_destroy(node_ptr L)
{
	//判断逻辑
	if(NULL==L)
	{
		printf("销毁失败\n");
		return ;
	}

	//释放逻辑
	//将所有普通节点释放
	while(!list_empty(L))
	{
		//调用头删函数
		list_delete_head(L);
	}

	//释放头结点
	free(L);
	L=NULL;
	printf("销毁成功\n");
}

头文件

复制代码
#ifndef __LINKLIST_H__
#define __LINKLIST_H__
#include<myhead.h>
typedef char datatype; //数据元素类型

//定义节点类型
typedef struct Node
{
	union
	{
		int len;//头结点数据域
		datatype data;//普通节点数据域
	};
	struct Node *next;  //指针域
}Node,*node_ptr;

//创建链表
node_ptr list_create();

//链表判空操作
int list_empty(node_ptr L);

//定义申请节点封装数据函数
node_ptr node_apply(datatype e);

//单向链表头插
int list_insert_head(node_ptr L,datatype e);

//单向链表的按位置查找返回节点
node_ptr list_find_node(node_ptr L,int pos);

//单向链表展示
int list_show(node_ptr L);

//单向链表任意位置插入
int list_insert_pos(node_ptr L,int pos,datatype e);

//单向链表的尾插
int list_insert_trail(node_ptr L,datatype e);

//单链表头删
int list_delete_head(node_ptr L);

//单向链表任意位置删除
int list_delete_pos(node_ptr L,int pos);

//单向链表的尾删
int list_delete_trail(node_ptr L);

//单向链表按值查找返回位置
int list_update_key(node_ptr L,datatype e);

//单向链表按位置进行修改
int list_update_pos(node_ptr L,int pos,datatype e);

//单向链表按值进行修改
int list_update_num(node_ptr L,datatype old_e,datatype new_e);

//单向链表的反转
int list_reverse(node_ptr L);

//单向链表的排序
int list_sort(node_ptr L);

//单向链表的去重
int list_remove(node_ptr L);

//单向链表的清空
int list_all_empty(node_ptr L);

//返回单向链表的长度
int list_long(node_ptr L);

//单向链表的释放
void list_destroy(node_ptr L);

#endif
相关推荐
Lsetea10 小时前
curl指定CA目录仍报证书不受信任:--capath与OpenSSL rehash排查
运维·https·ssl·openssl·curl
夜听莺儿鸣10 小时前
502-002_Linux驱动开发模块化编程
linux·驱动开发·模块化编程
wuminyu11 小时前
C++协程实现接收端的零拷贝Buffer管理原理剖析
java·linux·c语言·jvm·c++
优化Henry11 小时前
LTE 载波频率与频点配置详解
运维·网络·学习·5g·信息与通信
代码方舟11 小时前
数据科学风控实战:基于天远全能消金报告构建自动化信用评估网关
运维·人工智能·自动化
科力锐品牌君11 小时前
应用级灾备 | 海量非结构化数据如何实现高效数据保护
linux·运维·网络·安全·系统安全·数据安全·灾备
KaiwuDB12 小时前
KaiwuDB 运维实战04:DRBD + KaiwuDB——物联网场景下的低成本数据库高可用方案
运维·数据库·物联网·时序数据库·kaiwudb·aiot·多模数据库
zhangrelay12 小时前
ROS项目设计案例智能大模型正经乱答案例
linux·笔记·学习·ubuntu·机器人
福建佰胜张工12 小时前
A5E00839230西门子工业核心配件详解:参数、安装调试与故障运维全攻略
运维·网络·安全·自动化
流浪00112 小时前
Linux系统篇39——线程(四) pthread库的由来和线程的创建与等待
linux·操作系统·线程·pthread库