【链表的实现 - c语言】链表的数据结构 + 算法(操作)

1.基本搭建

链表的节点

//节点结构
typedef struct node
{
	int Data;
	struct node* Next;
}NODE,*PNODE;  // NODE 等同于struct node  PNODE 等同于struct node *

文件.c

/**
* @time 2023年6月6日13:36:34
* @content 链表的c实现
* @auther yzm
* 
*/


#include<stdio.h>
#include<malloc.h>//申请地址 开辟空间
#include<stdlib.h>//exit 终止程序

//节点结构
typedef struct node
{
	int Data;
	struct node* Next;
}NODE,*PNODE;  // NODE 等同于struct node  PNODE 等同于struct node *

//函数提前声明
PNODE Create_list();
void transverse_list(PNODE pHead);
bool isempty(PNODE pHead);
int list_length(PNODE pHead);
void sort_list(PNODE pHead);
bool insert_list(PNODE pHead, int poi, int val);
bool delete_list(PNODE pHead, int poi, int* val);
int main() {

	PNODE  pHead = NULL;//用于接受链表的头结点地址(链表的首地址)

	//链表的创建需要申请内存
	//返回申请的地址 头结点
	//创建链表
	pHead = Create_list();
	transverse_list(pHead);
	//排序
	//sort_list(pHead);
	// 插入
	insert_list(pHead,2,777);
	transverse_list(pHead);
	//删除
	int delval;
	if (delete_list(pHead, 3, &delval))
	{
		printf("删除%d成功", delval);
	}
	else {
		printf("删除失败");
	}
	//遍历打印链表
	transverse_list(pHead);

	//是否为空
	/*
	if (isempty(pHead))
	{
		printf("链表为空");
	}
	else {
		printf("链表不为空");
	}
	*/

	//返回链表的长度
	int len = list_length(pHead);
	printf("链表长度%d", len);
	return 0;
}

2.实现 链表的创建

PNODE Create_list() {
	//1.创建头结点
	PNODE pHead = (PNODE)malloc(sizeof(NODE));
	if (pHead == NULL)
	{
		printf("分配失败");
		exit(-1);
	}
	//2.创建 尾指针指向 尾部
	PNODE ptail = pHead;
	ptail->Next = NULL;

	//3.循环初始化节点数据
	int len;
	int value;
	printf("请输入链表的长度");
	scanf("%d", &len);
	for (int i = 0; i < len; i++)
	{
		printf("请输入第%d的数据\n",i+1);
		scanf("%d", &value);

		//4.创建节点
		PNODE pNew = (PNODE)malloc(sizeof(NODE));
		pNew->Data = value;
		pNew->Next = NULL;
		//挂载
		ptail->Next = pNew;
		//移动尾部指针
		ptail = pNew;
	}

	return pHead;
}

3.链表遍历输出

void transverse_list(PNODE pHead) {
	//参数 获得头结点的指针

	//1.创建遍历的指针
	PNODE pTran = pHead->Next;//pTran 指向第一个元素

	while (pTran != NULL)//遍历 pTran指针是否为空 不是空说明存在节点
	{
		//输出数据
		printf("%d ", pTran->Data);
		//移动指针
		pTran = pTran->Next;
	}
	printf("\n");

	return;

}

4.链表是否为空

//链表是否为空
bool isempty(PNODE pHead) {
	//当只有头结点的时候为空
	if (pHead->Next == NULL)
	{
		return true;
	}
	else {
		return false;
	}
}

5.链表长度

//返回长度
int list_length(PNODE pHead) {
	//获取第一个元素
	PNODE pchange = pHead->Next;
	int len = 0;
	while (pchange != NULL)
	{
		++len;
		pchange = pchange->Next;
	}

	return len;

}

6.链表排序

//实现链表的排序
void sort_list(PNODE pHead) {
	//冒泡排序  拿着第一个和后面全部比较 获得最大最小的值 
	//再拿着第二个和第二个后面比较 ...
	int i, j, t;
	PNODE p,q;
	int length = list_length(pHead);
	for (i = 0,p= pHead->Next; i < length - 1; i++,p=p->Next)//length-1 最后一个不需要排序
	{
		for (j = i+1,q=p->Next; j < length; j++, q=q->Next)//i 后面的值
		{
			//交换值
			if (p->Data > q->Data)
			{
				t = q->Data;
				q->Data = p->Data;
				p->Data = t;
			}
			
		}
	}
	return;
}

7.链表插入

//插入数据
bool insert_list(PNODE pHead,int poi,int val) {
	//链表的插入  首先获取插入位置的前一个节点  修改他的指向
	//参数  pHead 哪一个俩表  在哪个位置 poi 插入什么 val

	//1. 获取出入位置的前一个节点
	// 1 2 5 6 8    在5插入一个值 poi=3
	// 0 1 2 3 4
	int i=0;//用于获得poi 前一个节点  
	PNODE p= pHead;
	while (p->Next != NULL && i<poi-1)//为什么-1 如果是poi=3 i<3:0 1 2 就会到poi的位置 我们要做的是获取poi前一个
	{
		i++;
		p = p->Next;
	}

	//2.  输入限制  尾结点后面不能插入  输入poi负数或0 不能插入
	if (p->Next == NULL || i> poi - 1)//while 循环之后i 就是poi的前一个  poi输入-50 namei>poi
	{
		return false;
		
	}

	//3.插入
	//创建节点
	PNODE pNew = (PNODE)malloc(sizeof(NODE));
	if (pNew ==NULL)
	{
		printf("内存分配失败");
		exit(-1);
	}
	pNew->Data = val;
	//记录poi位置节点 t
	PNODE t = p->Next;
	//p指向新节点
	p->Next = pNew;
	//新节点指向 t
	pNew->Next = t;
	return true;
}

8.链表删除

//删除节点
bool delete_list(PNODE pHead, int poi, int* val) {
	//链表的删除  首先获取删除位置的前一个节点  修改他的指向
	//参数 那个链表 pHead 那个位置poi 删除后的记录纸

	//1. 获取出入位置的前一个节点
	// 1 2 5 6 8    在5插入一个值 poi=3
	// 0 1 2 3 4
	int i = 0;//用于获得poi 前一个节点  
	PNODE p = pHead;
	while (p->Next != NULL && i < poi - 1)//为什么-1 如果是poi=3 i<3:0 1 2 就会到poi的位置 我们要做的是获取poi前一个
	{
		i++;
		p = p->Next;
	}

	//2.  输入限制  尾结点后面不能插入  输入poi负数或0 不能插入
	if (p->Next == NULL || i > poi - 1)//while 循环之后i 就是poi的前一个  poi输入-50 namei>poi
	{
		return false;

	}
	//3.删除
	//记录删除的值 也就是poi位置节点
	PNODE deletenode = p->Next;
	* val = deletenode->Data;

	//修改指向
	p->Next = p->Next->Next;
	return true;

}

9.完整源码分享

/**
* @time 2023年6月6日13:36:34
* @content 链表的c实现
* @auther yzm
* 
*/


#include<stdio.h>
#include<malloc.h>//申请地址 开辟空间
#include<stdlib.h>//exit 终止程序

//节点结构
typedef struct node
{
	int Data;
	struct node* Next;
}NODE,*PNODE;  // NODE 等同于struct node  PNODE 等同于struct node *

//函数提前声明
PNODE Create_list();
void transverse_list(PNODE pHead);
bool isempty(PNODE pHead);
int list_length(PNODE pHead);
void sort_list(PNODE pHead);
bool insert_list(PNODE pHead, int poi, int val);
bool delete_list(PNODE pHead, int poi, int* val);
int main() {

	PNODE  pHead = NULL;//用于接受链表的头结点地址(链表的首地址)

	//链表的创建需要申请内存
	//返回申请的地址 头结点
	//创建链表
	pHead = Create_list();
	transverse_list(pHead);
	//排序
	//sort_list(pHead);
	// 插入
	insert_list(pHead,2,777);
	transverse_list(pHead);
	//删除
	int delval;
	if (delete_list(pHead, 3, &delval))
	{
		printf("删除%d成功", delval);
	}
	else {
		printf("删除失败");
	}
	//遍历打印链表
	transverse_list(pHead);

	//是否为空
	/*
	if (isempty(pHead))
	{
		printf("链表为空");
	}
	else {
		printf("链表不为空");
	}
	*/

	//返回链表的长度
	int len = list_length(pHead);
	printf("链表长度%d", len);
	return 0;
}
PNODE Create_list() {
	//1.创建头结点
	PNODE pHead = (PNODE)malloc(sizeof(NODE));
	if (pHead == NULL)
	{
		printf("分配失败");
		exit(-1);
	}
	//2.创建 尾指针指向 尾部
	PNODE ptail = pHead;
	ptail->Next = NULL;

	//3.循环初始化节点数据
	int len;
	int value;
	printf("请输入链表的长度");
	scanf("%d", &len);
	for (int i = 0; i < len; i++)
	{
		printf("请输入第%d的数据\n",i+1);
		scanf("%d", &value);

		//4.创建节点
		PNODE pNew = (PNODE)malloc(sizeof(NODE));
		pNew->Data = value;
		pNew->Next = NULL;
		//挂载
		ptail->Next = pNew;
		//移动尾部指针
		ptail = pNew;
	}

	return pHead;
}
void transverse_list(PNODE pHead) {
	//参数 获得头结点的指针

	//1.创建遍历的指针
	PNODE pTran = pHead->Next;//pTran 指向第一个元素

	while (pTran != NULL)//遍历 pTran指针是否为空 不是空说明存在节点
	{
		//输出数据
		printf("%d ", pTran->Data);
		//移动指针
		pTran = pTran->Next;
	}
	printf("\n");

	return;

}

//链表是否为空
bool isempty(PNODE pHead) {
	//当只有头结点的时候为空
	if (pHead->Next == NULL)
	{
		return true;
	}
	else {
		return false;
	}
}
//返回长度
int list_length(PNODE pHead) {
	//获取第一个元素
	PNODE pchange = pHead->Next;
	int len = 0;
	while (pchange != NULL)
	{
		++len;
		pchange = pchange->Next;
	}

	return len;

}
//实现链表的排序
void sort_list(PNODE pHead) {
	//冒泡排序  拿着第一个和后面全部比较 获得最大最小的值 
	//再拿着第二个和第二个后面比较 ...
	int i, j, t;
	PNODE p,q;
	int length = list_length(pHead);
	for (i = 0,p= pHead->Next; i < length - 1; i++,p=p->Next)//length-1 最后一个不需要排序
	{
		for (j = i+1,q=p->Next; j < length; j++, q=q->Next)//i 后面的值
		{
			//交换值
			if (p->Data > q->Data)
			{
				t = q->Data;
				q->Data = p->Data;
				p->Data = t;
			}
			
		}
	}
	return;
}
//插入数据
bool insert_list(PNODE pHead,int poi,int val) {
	//链表的插入  首先获取插入位置的前一个节点  修改他的指向
	//参数  pHead 哪一个俩表  在哪个位置 poi 插入什么 val

	//1. 获取出入位置的前一个节点
	// 1 2 5 6 8    在5插入一个值 poi=3
	// 0 1 2 3 4
	int i=0;//用于获得poi 前一个节点  
	PNODE p= pHead;
	while (p->Next != NULL && i<poi-1)//为什么-1 如果是poi=3 i<3:0 1 2 就会到poi的位置 我们要做的是获取poi前一个
	{
		i++;
		p = p->Next;
	}

	//2.  输入限制  尾结点后面不能插入  输入poi负数或0 不能插入
	if (p->Next == NULL || i> poi - 1)//while 循环之后i 就是poi的前一个  poi输入-50 namei>poi
	{
		return false;
		
	}

	//3.插入
	//创建节点
	PNODE pNew = (PNODE)malloc(sizeof(NODE));
	if (pNew ==NULL)
	{
		printf("内存分配失败");
		exit(-1);
	}
	pNew->Data = val;
	//记录poi位置节点 t
	PNODE t = p->Next;
	//p指向新节点
	p->Next = pNew;
	//新节点指向 t
	pNew->Next = t;
	return true;
}

//删除节点
bool delete_list(PNODE pHead, int poi, int* val) {
	//链表的删除  首先获取删除位置的前一个节点  修改他的指向
	//参数 那个链表 pHead 那个位置poi 删除后的记录纸

	//1. 获取出入位置的前一个节点
	// 1 2 5 6 8    在5插入一个值 poi=3
	// 0 1 2 3 4
	int i = 0;//用于获得poi 前一个节点  
	PNODE p = pHead;
	while (p->Next != NULL && i < poi - 1)//为什么-1 如果是poi=3 i<3:0 1 2 就会到poi的位置 我们要做的是获取poi前一个
	{
		i++;
		p = p->Next;
	}

	//2.  输入限制  尾结点后面不能插入  输入poi负数或0 不能插入
	if (p->Next == NULL || i > poi - 1)//while 循环之后i 就是poi的前一个  poi输入-50 namei>poi
	{
		return false;

	}
	//3.删除
	//记录删除的值 也就是poi位置节点
	PNODE deletenode = p->Next;
	* val = deletenode->Data;

	//修改指向
	p->Next = p->Next->Next;
	return true;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值