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
相关推荐
云空43 分钟前
《DeepSeek 网页/API 性能异常(DeepSeek Web/API Degraded Performance):网络安全日志》
运维·人工智能·web安全·网络安全·开源·网络攻击模型·安全威胁分析
深度Linux1 小时前
Linux网络编程中的零拷贝:提升性能的秘密武器
linux·linux内核·零拷贝技术
没有名字的小羊2 小时前
Cyber Security 101-Build Your Cyber Security Career-Security Principles(安全原则)
运维·网络·安全
m0_465215792 小时前
TCP & UDP Service Model
服务器·网络·tcp/ip
千夜啊2 小时前
Nginx 运维开发高频面试题详解
运维·nginx·运维开发
存储服务专家StorageExpert3 小时前
答疑解惑:如何监控EMC unity存储系统磁盘重构rebuild进度
运维·unity·存储维护·emc存储
chian-ocean4 小时前
从理论到实践:Linux 进程替换与 exec 系列函数
linux·运维·服务器
拎得清n5 小时前
UDP编程
linux
敖行客 Allthinker5 小时前
从 UTC 日期时间字符串获取 Unix 时间戳:C 和 C++ 中的挑战与解决方案
linux·运维·服务器·c++
JunLan~5 小时前
Docker 部署 GLPI(IT 资产管理软件系统)
运维·docker·容器