链表基本操作的C语言简单实现

        实现动态单向链表的基本操作,包括新建、输出、删除、插入。

        浅显易懂,方便初学者模仿。

//构建存放学生信息的单向动态链表
#include<stdio.h>
#include<malloc.h>
#define NULL 0
#define LEN sizeof(struct student)        //用来计算结构体所占空间的大小
struct student
{
	long num;
	float score;
	struct student * next;
};
int n;                                    //全局变量n用来统计链表中的节点个数,初值为0.

struct student * creat(void)              //定义一个函数,功能是创建动态链表,返回值是一个指向student类型的结构体的指针
{
	struct student * head;                //定义头指针
	struct student * p1,* p2;
	head = NULL;                          //头结点的初始化
	n = 0;                                //开始的时候链表为空
	p1 = ( struct student * )malloc(LEN); //malloc函数用来开辟第一个大小为student结构体的大小的内存空间,其返回值是(不指向任何类型数据的指针),所以要进行强制类型转换,变成和p1,p2一样的类型
	p2 = p1;                               //这里必须要给p2也赋值,不然不能实现空链表的正常创建
	scanf("%ld %f",&p1->num,&p1->score);  //先接收第一个节点的数据
	while(p1->num != 0)                   //必须合法的num才需要新建节点
	{
		n = n + 1;
		if(n == 1)                              //这里判断是不是第一个节点
			head = p1;
		p2 = p1;                                //保留p1的指向,head之后会固定不变,所以用p2来跟随p1
		p1 = ( struct student * )malloc(LEN);   //新开辟内存单元
		p2->next = p1;
		scanf("%ld %f",&p1->num,&p1->score);   //输入下一个节点的信息
	}
	p2->next = NULL;
	return(head);
}

void print(struct student *head)               //输出链表的函数
{
	struct student * p;
	if(head != NULL)
	{
		p = head;
		do
		{
			printf("%ld %.2f\n",p->num,p->score);
			p = p->next;
		}while(p != NULL);
	}
	else
		printf("Nothing.\n");
}

struct student * del(struct student * head,long num)       //用来删除对应学校的学生
{
	struct student *p1,*p2;
	if(head == NULL)        //空链表时
	{
		printf("This is an empty list.\n");
		return(head);
	}
	else                    //链表非空的时候
	{
		p1 = head;
		while(p1->num != num && p1->next != NULL)      //寻找num对应的结点,直至找到或者遍历完整个链表
		{
			p2 = p1;                                   //p2一直指向的是之后的p1的前一个结点
			p1 = p1->next;
		}
		if(p1->num == num)           //找到了,即使是最后一个结点才找到
		{
			if(head->num == num)     //找到的是头结点
				head = p1->next;
			else
			{
				p2->next = p1->next;
			}
			printf("\ndelete:%ld\n",num);
			n = n-1;
		}
		else                         //找遍了,却找不到的时候
			printf("not found.\n");
	}
	return(head);
}

struct student * in(struct student * head,struct student * stud)       //用来按照学号的由小到大的顺序插入对应学生
{
	struct student *p0,*p1,*p2;
	p1 = head;
	p0 = stud;
	if(head == NULL)      //链表为空,插入到队首
	{
		head = p0;
		p0->next = NULL;
	}
	else
	{
		while((p0->num > p1->num) && (p1->next != NULL))   //在队中寻找适当的位置,找到或者适当的位置在表尾,之后退出
		{
			p2 = p1;                                        //保留上一个位置
			p1 = p1->next;
		}
		if(p0->num <= p1->num)                             //找到了这个元素的适当位置
		{
			if(head == p1)                                  //如果这个适当的位置在表首
			{
				head = p0;
				p0->next = p1;
			}
			else                                             //在表中的时候
			{
				p2->next = p0;
				p0->next = p1;
			}
		}
		else                                               //需要放到表尾的时候
		{
			p1->next = p0;
			p0->next = NULL;
		}
	}
	n = n + 1;
	return(head);
}

void main()
{
	struct student * p,*p1;
	long num;
	int over,ok;
	struct student stud;            //用来存放刚刚插入的结点的信息,不能是指针,因为定义指针没有开辟内存空间

	//新建
	p = creat();

	//输出
	printf("数据如下:\n");
	print(p);
	printf("结点个数是%d\n",n);

	//删除
	printf("If you want to delete a point,Please input 1:\nIf not,input 0:\n");
	scanf("%d",&over);
	do
	{
		printf("Please input the number of the student you want to delete:\n");
		scanf("%ld",&num);
		p = del(p,num);
		printf("\nAfter deleting:\n");
		print(p);
		printf("此时结点个数是%d\n",n);
		printf("If you want to delete a point,Please input 1:\nIf not,input 0:\n");
		scanf("%d",&over);
	}while(over == 1);

	//插入
	printf("If you want to insert a point,Please input 1:\nIf not,input 0:\n");
	scanf("%d",&ok);
	do
	{
		printf("Please input the number of the student you want to insert:\n");
		scanf("%ld %f",&stud.num,&stud.score);
		p1 = &stud;                      //取一个结构体的初始地址
		p = in(p,p1);
		printf("\nAfter inserting:\n");
		print(p);
		printf("此时结点个数是%d\n",n);
		printf("If you want to insert a point,Please input 1:\nIf not,input 0:\n");
		scanf("%d",&ok);
	}while(ok == 1);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值