【C语言】单链表的基本功能实现

4 篇文章 0 订阅
2 篇文章 0 订阅

单链表的基本功能实现(基于C语言)

声明(技术有限,仅限参考,可直接通过GCC编译使用,大神勿喷)

也真诚希望各位可以提些真实有用的意见


基本功能

  1. 新建链表
  2. 初始化
  3. 遍历
  4. 计算长度
  5. 删除单个结点
  6. 插入新结点
  7. 修改结点内容
  8. 查看单个结点
  9. 清空链表
  10. 销毁链表

代码区

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LinkList struct ListNode

//数据结点
struct DataNode
{
	int num;
	char name[21];
	char addr[31];
	int score[2];
};


//链表结点
LinkList
{
	struct DataNode *data;		//数据域
	LinkList *next;				//指针域
};




//创建结点
LinkList* creat_LinkList()
{

	//开辟结点空间
	LinkList* newNode = malloc(sizeof(LinkList));

	//开辟内部结点空间
	newNode->data = malloc(sizeof(struct DataNode));

	//指针域置空
	newNode->next = NULL;
	
	return newNode;
}




//初始化链表
LinkList* init_LinkList(LinkList* newNode)
{

	if (newNode == NULL)
	{
		return NULL;
	}

	//引出一个头结点(pHeader data置为空)
	LinkList* pHeader = newNode;
	LinkList* pCurrent = newNode;

	int val = -1;

	//初始化
	while(1)
	{
		printf("Input -1 is colse!!!\n");
		scanf("%d",&val);

		if(val == -1) break;

		pCurrent->next = creat_LinkList();

		printf("Input num,name,addr and two score:\n");
		scanf("%d",&pCurrent->next->data->num);
		scanf("%s",pCurrent->next->data->name);
		scanf("%s",pCurrent->next->data->addr);
		scanf("%d",&pCurrent->next->data->score[0]);
		scanf("%d",&pCurrent->next->data->score[1]);

		pCurrent = pCurrent->next;
	}

	//末尾置空
	pCurrent->next = NULL;

	return pHeader;
}




//计算链表大小
void size_LinkList(LinkList* pHeader)
{
	//判空
	if(pHeader->next == NULL)
	{
		printf("Count:NULL LinkList\n");
		return;
	}

	//从头结点->next开始
	LinkList* pCurrent = pHeader->next;
	int size = 1;

	while(pCurrent)
	{
		pCurrent = pCurrent->next;
		size++;
	}

	//使用long int输出,否则Linux编译无法通过
	printf("The LinkList have %d node(include a NULL node)\n", size);
	printf("The LinkList size is %ld Byte\n", size * sizeof(LinkList));		
}




//删除结点	根据num
void delete_LinkList(LinkList* pHeader)
{

	//自定义num
	printf("Input Delete Num:\n");
	int num = -1;
	scanf("%d",&num);

	//判空
	if(pHeader == NULL)
	{
		printf("Delete Fail: NULL LinkList\n");
		return;
	}

	//辅助指针
	LinkList* pCurrent = pHeader->next;

	//记录pCurrent
	LinkList* pTemp = pCurrent;

	//遍历寻找结点
	while(pCurrent)
	{
		if(pCurrent->data->num == num)
			break;

		//继承pCurrent
		pTemp = pCurrent;
		pCurrent = pCurrent->next;
	}

	//判断是否找到
	if (pCurrent == NULL)
	{
		printf("Delete Fail: NOT FIND\n");
		return;
	}

	//衔接
	pTemp->next = pCurrent->next;

	//释放
	free(pCurrent);

	printf("Delete Success!\n");

}




//遍历链表
void foreach_LinkList(LinkList* pHeader)
{

	if (pHeader->next == NULL)
	{
		//空表
		printf("Foreach:NULL LinkList\n");
		return;
	}

	//辅助指针
	LinkList* pCurrent = pHeader->next;

	printf("Number\tName\tAddr\tscore1\tscore2\n");

	//遍历
	while(pCurrent)
	{
		printf("%d\t",pCurrent->data->num);
		printf("%s\t",pCurrent->data->name);
		printf("%s\t",pCurrent->data->addr);
		printf("%d\t",pCurrent->data->score[0]);
		printf("%d\n",pCurrent->data->score[1]);
		
		pCurrent = pCurrent->next;
	}

}




//计算链表大小	用于insert_LinkList()中,size_LinkList()不适用于此处,便于维护,重新定义一个
int size_LinkListNode(LinkList* pHeader)
{

	int size = 0;

	LinkList* pCurrent = pHeader->next;

	while(pCurrent) 
	{
		size++;
		pCurrent = pCurrent->next;
	}


	return size;
}




//增加新结点,按位置添加
void insert_LinkList(LinkList* pHeader)
{
	//判空
	if (pHeader == NULL)
	{
		printf("Insert Fail: NULL LinkList!!!\n");
		return;
	}

	printf("Input a insert station:\n");

	int station = -1;
	scanf("%d",&station);

	if (station < 1 || station > size_LinkListNode(pHeader))
	{
		printf("Insert Fail: station error!!!\n");
		return;
	}

	//辅助指针
	LinkList* pCurrent = pHeader;

	int staTemp = 1;
	while(staTemp != station)
	{
		pCurrent = pCurrent->next;
		staTemp++;
	}

	//创建新结点
	LinkList* pTemp = creat_LinkList();

	if (pTemp == NULL)
	{
		printf("Creat NewNode Fail\n");
		return;
	}

	//格式输出
	printf("Input NewNode num,name,addr and two score:\n");
	scanf("%d",&pTemp->data->num);
	scanf("%s",pTemp->data->name);
	scanf("%s",pTemp->data->addr);
	scanf("%d",&pTemp->data->score[0]);
	scanf("%d",&pTemp->data->score[1]);

	//衔接
	pTemp->next = pCurrent->next;
	pCurrent->next = pTemp;

}



//修改结点	按num
void update_LinkList(LinkList* pHeader)
{

	//初始化tnum,作为num对比变量
	int tnum = -1;

	//提示
	printf("Input Update Number:\n");
	scanf("%d",&tnum);

	//pCurrent指针继承pHeader,从第一个有数据结点开始
	LinkList* pCurrent = pHeader->next;

	//寻找与指定tnum相符的结点
	while(pCurrent)
	{
		//找到
		if(pCurrent->data->num == tnum)
			break;

		//未找到
		pCurrent = pCurrent->next;
	}

	//判断链表是否到末尾(未找到)
	if(pCurrent == NULL)
	{
		printf("NOT FIND\n");
		return;
	}

	//找到
	printf("Success! Found\n");

	//开始修改,为类目名派序号
	printf("Selete Item:\n1.Num    2.Name    3.Addr    4.Score1    5.Score2\n");

	//item  记录修改的类目
	int item = 0;
	scanf("%d",&item);

	//选项不符
	if (item < 0 || item >5)
	{
		printf("Selete Item Error\n");
		return;
	}

	//修改内容
	switch(item)
	{

		//修改num
		case 1:
		{
			printf("New Number is:\n");
			int num_temp = 0;		//num_temp改动后分数
			scanf("%d",&num_temp);
			pCurrent->data->num = num_temp;		//新分数赋值
			break;
		}

		//修改name
		case 2:
		{
			printf("New Name is:\n");
			char* name_temp = malloc(sizeof(char*));	//记录name_temp指针分配空间
			scanf("%s",name_temp);
			strcpy(pCurrent->data->name,name_temp);		//将name_temp内容赋予表中
			break;
		}

		//修改addr
		case 3:
		{
			printf("New Addr is:\n");
			char* addr_temp = malloc(sizeof(char*));
			scanf("%s",addr_temp);
			strcpy(pCurrent->data->addr,addr_temp);
			break;
		}

		//修改分数
		case 4:
		{
			printf("New Score1 is:\n");
			int score1_temp = 0;
			scanf("%d",&score1_temp);
			pCurrent->data->score[0] = score1_temp;
			break;
		}

		//修改分数
		case 5:
		{
			printf("New Score2 is:\n");
			int score2_temp = 0;
			scanf("%d",&score2_temp);
			pCurrent->data->score[1] = score2_temp;
			break;
		}
	}

	//成功提示
	printf("Update Success!\n");
}




//查看单个结点
void read_LinkList(LinkList* pHeader)
{

	//判空
	if (pHeader == NULL)
		return;

	printf("Input read Number:\n");

	//记录临时num变量(用户自定义)
	int num_temp = -1;
	scanf("%d",&num_temp);

	//从首个有数据结点开始
	LinkList* pCurrent = pHeader->next;

	//寻找对应结点
	while(pCurrent)
	{
		//找到
		if(pCurrent->data->num == num_temp)
			break;

		//未找到继续
		pCurrent = pCurrent->next;
	}

	//判断是否到表尾
	if (pCurrent == NULL)
	{
		printf("Not Found\n");
		return;
	}

	//print格式
	printf("This Node item have:\n");
	printf("%d\t",pCurrent->data->num);
	printf("%s\t",pCurrent->data->name);
	printf("%s\t",pCurrent->data->addr);
	printf("%d\t",pCurrent->data->score[0]);
	printf("%d\n",pCurrent->data->score[1]);
}




//清空链表
void clean_LinkList(LinkList* pHeader)
{
	//判空
	if (pHeader == NULL)
	{
		return;
	}

	//临时指针
	LinkList* p,*q;

	p = pHeader->next;

	//循环free
	while(p)
	{
		q = p->next;
		free(p);
		p = q;
	}

	//头结点置空
	pHeader->next = NULL;
	printf("Clean LinkList Success\n");
}




//销毁链表
void destroy_LinkList(LinkList* pHeader)
{
	//判空
	if (pHeader == NULL)
	{
		return;
	}

	//循环释放
	while(pHeader)
	{
		LinkList* p = pHeader->next;
		free(pHeader);
		pHeader = p;
	}

	//置空
	pHeader = NULL;
	printf("Destroy LinkList Success\n");
}




int main(void)
{

	//创建
	LinkList* pHeader = creat_LinkList();

	//初始化
	init_LinkList(pHeader);
	
	//遍历
	printf("--------------------------\n");
	foreach_LinkList(pHeader);

	//计算链表大小
	printf("--------------------------\n");
	size_LinkList(pHeader);

	//删除结点
	printf("--------------------------\n");
	delete_LinkList(pHeader);
	foreach_LinkList(pHeader);

	//插入新结点
	printf("--------------------------\n");
	insert_LinkList(pHeader);
	foreach_LinkList(pHeader);

	//修改
	printf("--------------------------\n");
	update_LinkList(pHeader);
	foreach_LinkList(pHeader);

	//查看单个
	read_LinkList(pHeader);

	//清空
	printf("--------------------------\n");
	clean_LinkList(pHeader);
	foreach_LinkList(pHeader);

	//销毁
	printf("--------------------------\n");
	destroy_LinkList(pHeader);
	size_LinkList(pHeader);
	foreach_LinkList(pHeader);

	return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我姥爷是校长

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值