数据结构(c语言版)------单链表的基本操作(包括单链表的创建、插入、删除、排序等)

单链表的基本操作

单链表的结构

typedef struct node {
	int data;
	struct node *next;
}Node;

单链表的创建(头插法)

//头插法创建链表
bool CreatList(Node *l) {
	if (l==NULL)
	{
		return false;
	}
	printf("请输入链表的长度:");
	int len;
	scanf("%d", &len);
	l->next = NULL;
	l->data = len;
	Node *p;
	srand((int)time(0));
	for (int i = 0; i < len; i++)
	{
		p = (Node *)malloc(sizeof(Node));
		p->data = rand() % 100 + 1;//产生随机数
		p->next = l->next;
		l->next = p;
	}
	return true;
}

单链表的创建(尾插法)

//尾插法创建链表
bool CreatList(Node *l) {
	if (l==NULL)
	{
		return false;
	}
	printf("请输入链表的长度:");
	int len;
	scanf("%d", &len);
	l->next = NULL;
	l->data = len;
	Node *q = l;
	Node *p;
	srand((int)time(0));
	for (int i = 0; i < len; i++)
	{
		p = (Node *)malloc(sizeof(Node));
		p->data = rand() % 100 + 1;//产生随机数
		q->next = p;//将表尾结点指向新添加的节点
		q = p;//将新添加的节点置为尾结点
	}
	q->next = NULL;
	return true;
}

获取单链表的长度

int LengthList(Node *l) {
	Node *p = l->next;
	int i = 0;
	while (p)
	{
		i++;
		p = p->next;
	}
	return i;//依次遍历单链表,并返回他的长度
}

单链表的插入(在某个节点后插入)

bool InsertData(Node *l, int i, int data) {
	Node *p = l->next;
	int j = 0;
	while (p&&j<i-1)
	{
		j++;
		p = p->next;
	}
	if (p==NULL||j>i-1)
	{
		return false;//判断输入的下标是否合法
	}
	Node *q = (Node *)malloc(sizeof(Node));
	q->data = data;
	q->next = p->next;//将待插入值与p下个节点进行连接
	p->next = q;//将p的下一个节点指向待插入节点
	return true;
}

单链表删除某个节点(根据下标删除当前节点)

bool DeleteByData(Node *l, int i) {

	Node *p = l->next;
	int j = 1;
	while (p&&j<i-1)
	{

		p = p->next;
		j++;//先找到待删除节点的前一个节点
	}
	if (p == NULL || j > i - 1)
	{
		return false;//判断下标是否合法
	}
	Node *q = p->next;

	p->next = q->next;//找到待删除节点,并将待删除节点的前一个节点与其后一个节点相连
	free(q);//释放资源
	return true;
}

根据下标获取当前节点的值

int GetByIndex(Node *l, int i) {
	Node *p = l->next;
	int j = 1;
	while (p&&j<i-1)
	{
		j++;
		p = p->next;//先找到待查找节点的前一个节点
	}
	if (p == NULL || j > i - 1)
	{
		return -1;//判断下标是否合法
	}
	
	return p->next->data;//返回待查找节点的值
}

根据下标修改当前节点的值

bool UpdataByIndex(Node *l, int i, int data) {
	Node *p = l->next;
	int j = 1;
	while (p&&j < i - 1)
	{
		j++;
		p = p->next;//先找到待更新节点的前一个节点
	}
	if (p == NULL || j > i - 1)
	{
		return false;//判断下标是否合法
	}
	p->next->data = data;//更新它的值
	return true;
}

判断当前连表是否为空

bool IsEmpty(Node *l) {
	Node *p = l->next;
	if (p==NULL)
	{
		return false;//通过判断头结点的下一个是否为空来确定链表是不是空的
	}
	return true;
}

清空单链表

void ClearList(Node *l) {
	Node *p = l->next;
	if (p==NULL||l==NULL)
	{
		printf("\n单链表为空\n");

	}
	else {
		Node *q;
		while (p)
		{
			q = p->next;
			
			free(p);//逐个删除节点
			p = q;
		}
		l->next = NULL;//最后将其头结点的下一个节点置为空
		printf("\n全部清空\n");
	}
	
}

对单链表进行排序

void SortList(Node *l) {
	Node *p, *q;
	int temp;
	for (p = l->next;p!=NULL;p = p->next)
	{
		for (q = p; q != NULL; q = q->next) {
			if (p->data>q->data)
			{
				temp = p->data;
				p->data = q->data;//交换节点的值
				q->data = temp;
			}
		}
	}
	printf("\n排序后的数据为:\n");
	printfList(l);
}

根据值查找元素的下标

int SearchByData(Node *l, int data) {
	Node *p = l->next;
	int i = 1;//标记下标
	while (p)
	{
		if (p->data == data)
		{
			return i;//如果和指定数值相等就返回他的下标
		}
		i++;
		p = p->next;

	}
	return -1;
}

根据值删除节点

bool DeleteByData(Node *l, int data) {
	Node *p = l->next;
	int i = 1;
	while (p)
	{
		if (p->data==data)
		{
			if (DeleteByIndex(l, i))//先找到指定值的下标,然后再根据下标删除指定元素
			{
				return true;
			}

		}
		i++;
		p = p->next;
	}
	return false;
}

bool DeleteByIndex(Node *l, int i) {

	Node *p = l->next;
	int j = 1;
	while (p&&j<i-1)
	{

		p = p->next;
		j++;//先找到待删除节点的前一个节点
	}
	if (p == NULL || j > i - 1)
	{
		return false;//判断下标是否合法
	}
	Node *q = p->next;

	p->next = q->next;//找到待删除节点,并将待删除节点的前一个节点与其后一个节点相连
	free(q);//释放资源
	return true;
}

遍历单链表

void printfList(Node *l) {
	Node *p = l->next;
	while (p)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}

删除指定范围内的元素的值

void DeleteList(Node *l, int min, int max) {
	Node *p = l;//将目标链表赋给一个新的链表
	Node *q = l->next;
	while (q)
	{
		if (q->data<min || q->data>max) {
			p->next = q;
			p = q;//如果不在指定范围内,就利用尾插法将其添加到新的表中
			q = q->next;
		}
		else {
			Node *l1 = q;
			q = q->next;
			free(l1);//如果在这个范围内就释放内存
		}

	}
	p->next = NULL;
}

全部代码展示

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<time.h>
typedef struct node {
	int data;
	struct node *next;
}Node;
bool CreatList(Node *l);//单链表的创建
int LengthList(Node *l);//获取单链表的长度
bool InsertData(Node *l, int i, int data);//在某个节点后插入元素
bool DeleteByIndex(Node *l, int i);//删除指定节点(根据下标)
int GetByIndex(Node *l, int i);//获取某个位置的元素
bool UpdataByIndex(Node *l, int i, int data);//更新某个位置的值
bool IsEmpty(Node *l);//判断连表是否为空
void printfList(Node *l);//遍历链表
void ClearList(Node *l);//清空单链表
void SortList(Node *l);//对单链表进行排序
int SearchByData(Node *l, int data);//根据值返回值的下标
bool DeleteByData(Node *l, int data);//根据值删除某个节点
int main() {
	bool flag = true;
	int choice;
	int i;
	int data;
	Node *l = (Node *)malloc(sizeof(Node));
	while (flag)
	{
		printf("\n=====单链表的基本操作=====\n");
		printf("1.单链表的创建\n");
		printf("2.单链表的长度\n");
		printf("3.单链表的插入(在某个节点后)\n");
		printf("4.单链表的删除(删除某个节点)\n");
		printf("5.获取某个节点位置的值\n");
		printf("6.根据指定下标修改元素的值\n");
		printf("7.判断单链表是否为空\n");
		printf("8.清空单链表\n");
		printf("9.单链表的遍历\n");
		printf("10.单链表的排序\n");
		printf("11.获取某个节点的下标\n");
		printf("12.删除单链表中指定的值\n");
		printf("13.退出程序\n");
		printf("============================\n");
		printf("请输入你的选择:");
		scanf("%d", &choice);
		switch (choice)
		{
		case 1:
			if (CreatList(l))
			{
				printf("\n单链表创建成功\n");
			}
			else {
				printf("\n单链表创建失败\n");
			}
				break;
		case 2:
		
				printf("\n单链表的长度为:%d\n", LengthList(l));
				break;
		case 3:
			printf("i,data=");
			scanf("%d", &i);
			scanf("%d", &data);
			if (InsertData(l, i, data))
			{
				printf("\n插入成功\n");
			}
			else {
				printf("\n插入失败\n");
			}
				break;
		case 4:
			printf("i = ");
			scanf("%d", &i);
			if (DeleteByIndex(l, i))
			{
				printf("\n删除成功\n");
			}
			else {
				printf("\n删除失败\n");
			}
			break;
		case 5:
			printf("i = ");
			scanf("%d", &i);
			if (GetByIndex(l, i)!=-1)
			{
				printf("\n%d 位置的值为:%d\n", i, GetByIndex(l, i));
			}
			break;
		case 6:
			printf("i,data=");
			scanf("%d", &i);
			scanf("%d", &data);
			if (UpdataByIndex(l, i,data))
			{
				printf("\n修改成功\n");
			}
			else {
				printf("\n修改失败\n");
			}
			break;
		case 7:
			if (IsEmpty(l))
			{
				printf("\n单链表不为空\n");
			}
			else {
				printf("\n单链表为空\n");
			}
			break;
		case 8:
			ClearList(l);
			break;
		case 9:
			printfList(l);
			break;
		case 10:
			SortList(l);
			break;
		case 11:
			printf("data = ");
			scanf("%d", &data);
			if (SearchByData(l, data)!=-1)
			{
				printf("\n%d 的下标为:%d\n", data, SearchByData(l, data));
			}
			else {
				printf("\n找不到该值\n");
			}
			break;
		case 12:
			printf("data = ");
			scanf("%d", &data);
			if (DeleteByData(l, data))
			{
				printf("\n删除成功\n");
			}
			else {
				printf("\n没有找到该数据\n");
			}
			break;
		case 13:
			flag = false;
			break;
		}

	}
	printf("\n退出程序。。。。。。。。。。\n");
}
//尾插法创建链表
bool CreatList(Node *l) {
	if (l==NULL)
	{
		return false;
	}
	printf("请输入链表的长度:");
	int len;
	scanf("%d", &len);
	l->next = NULL;
	l->data = len;
	Node *q = l;
	Node *p;
	srand((int)time(0));
	for (int i = 0; i < len; i++)
	{
		p = (Node *)malloc(sizeof(Node));
		p->data = rand() % 100 + 1;//产生随机数
		q->next = p;//将表尾结点指向新添加的节点
		q = p;//将新添加的节点置为尾结点
	}
	q->next = NULL;
	return true;
}
int LengthList(Node *l) {
	Node *p = l->next;
	int i = 0;
	while (p)
	{
		i++;
		p = p->next;
	}
	return i;//依次遍历单链表,并返回他的长度
}
bool InsertData(Node *l, int i, int data) {
	Node *p = l->next;
	int j = 0;
	while (p&&j<i-1)
	{
		j++;
		p = p->next;
	}
	if (p==NULL||j>i-1)
	{
		return false;//判断输入的下标是否合法
	}
	Node *q = (Node *)malloc(sizeof(Node));
	q->data = data;
	q->next = p->next;//将待插入值与p下个节点进行连接
	p->next = q;//将p的下一个节点指向待插入节点
	return true;
}
bool DeleteByIndex(Node *l, int i) {

	Node *p = l->next;
	int j = 1;
	while (p&&j<i-1)
	{

		p = p->next;
		j++;//先找到待删除节点的前一个节点
	}
	if (p == NULL || j > i - 1)
	{
		return false;//判断下标是否合法
	}
	Node *q = p->next;

	p->next = q->next;//找到待删除节点,并将待删除节点的前一个节点与其后一个节点相连
	free(q);//释放资源
	return true;
}
int GetByIndex(Node *l, int i) {
	Node *p = l->next;
	int j = 1;
	while (p&&j<i-1)
	{
		j++;
		p = p->next;//先找到待查找节点的前一个节点
	}
	if (p == NULL || j > i - 1)
	{
		return -1;//判断下标是否合法
	}
	
	return p->next->data;//返回待查找节点的值
}

bool UpdataByIndex(Node *l, int i, int data) {
	Node *p = l->next;
	int j = 1;
	while (p&&j < i - 1)
	{
		j++;
		p = p->next;//先找到待更新节点的前一个节点
	}
	if (p == NULL || j > i - 1)
	{
		return false;//判断下标是否合法
	}
	p->next->data = data;//更新它的值
	return true;
}
bool IsEmpty(Node *l) {
	Node *p = l->next;
	if (p==NULL)
	{
		return false;//通过判断头结点的下一个是否为空来确定链表是不是空的
	}
	return true;
}
void ClearList(Node *l) {
	Node *p = l->next;
	if (p==NULL||l==NULL)
	{
		printf("\n单链表为空\n");

	}
	else {
		Node *q;
		while (p)
		{
			q = p->next;
			
			free(p);//逐个删除节点
			p = q;
		}
		l->next = NULL;//最后将其头结点的下一个节点置为空
		printf("\n全部清空\n");
	}
	
}
void SortList(Node *l) {
	Node *p, *q;
	int temp;
	for (p = l->next;p!=NULL;p = p->next)
	{
		for (q = p; q != NULL; q = q->next) {
			if (p->data>q->data)
			{
				temp = p->data;
				p->data = q->data;//交换节点的值
				q->data = temp;
			}
		}
	}
	printf("\n排序后的数据为:\n");
	printfList(l);
}
int SearchByData(Node *l, int data) {
	Node *p = l->next;
	int i = 1;//标记下标
	while (p)
	{
		if (p->data == data)
		{
			return i;//如果和指定数值相等就返回他的下标
		}
		i++;
		p = p->next;

	}
	return -1;
}
bool DeleteByData(Node *l, int data) {
	Node *p = l->next;
	int i = 1;
	while (p)
	{
		if (p->data==data)
		{
			if (DeleteByIndex(l, i))//先找到指定值的下标,然后再根据下标删除指定元素
			{
				return true;
			}

		}
		i++;
		p = p->next;
	}
	return false;
}
void DeleteList(Node *l, int min, int max) {
	Node *p = l;//将目标链表赋给一个新的链表
	Node *q = l->next;
	while (q)
	{
		if (q->data<min || q->data>max) {
			p->next = q;
			p = q;//如果不在指定范围内,就利用尾插法将其添加到新的表中
			q = q->next;
		}
		else {
			Node *l1 = q;
			q = q->next;
			free(l1);//如果在这个范围内就释放内存
		}

	}
	p->next = NULL;
}
void printfList(Node *l) {
	Node *p = l->next;
	while (p)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何一平?

你的收获就是我学习的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值