C语言简单入门之结构体和链表

C语言的链表也是一个很重要很难啃的骨头,我是这么觉得的!

以下只是个人对链表的总结和记录方便日后复习所用,如有错误,请留言狠批,谢谢!

先说下链表的简单实现:

 如上图,我们定义一个结构体:

1,2,3,4,5是结构体数据。a,b,c,d,e则是指针变量,在链表中是1.next的表达方式

首先,结构体的名字指向的是链表的首地址(也就是1的地址,而a的存放是2的地址),这样指下去。一个简单的列表就形成了。需要注意的是,链表最后的数据中e的位置需要指向NULL,这样才使得链表暂时时结束的。后面我们还会学到对链表的增、删、查等操作!

 

下面我们就定义了一个简单的链表,并给链表赋值,并打印值

 

/*
链表的简单实现
*/
struct Stu
{
	long num;
	double score;
	struct Stu *next;
};
void main()
{
	struct Stu a, b, c, *head;

	a.num = 10001;
	a.score = 98;
	b.num = 10002;
	b.score = 89;
	c.num = 10003;
	c.score = 90;

	head = &a;
	a.next = &b;
	b.next = &c;
	c.next = NULL;

	do {
		printf("%d     %5.2f\n", head->num, head->score);
		head = head->next;
	} while (head!=NULL);

}

 

 上面赋值和查数据都可以了

 

链表的插入:

(三种情况,最前面插入。中间插入。最后面插入)

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define LEN sizeof(struct Stu)   //宏定义,利用sizeof求出结构体的大小。方便我们在代码中向内存要空间
int n;  //总共输入的学生统计
struct Stu        //定义一个学生结构体
{
	long num;   //学号
	double score;//分数
	struct Stu *next;//指向下一个的指针
};

struct Stu *create();    //创建链表
void print(struct Stu *head);//打印链表
struct Stu *insert(struct Stu *head, struct Stu *insert);  //插入链表


void main()
{
	struct Stu *stu,*p, sert;   //输入数据创建一个链表,并打印出来
	stu = create();
	p = stu;
	print(p);

	printf(" Here please create need insert is data \n");
	//输入要插入的数据
	printf("please input stu num:");
	scanf_s("%d", &sert.num);
	printf("please input stu score:");
	scanf_s("%lf", &sert.score);
	p = insert(stu, &sert);
	print(p);

	printf("insert data OK;");


}


struct Stu *create()
{
	//原理:先定义三个指针变量,p1和p2默认向内存求取了一个结构体大小的空间,head默认指向空地址
	//接收用户第一次输入的学号和分数,存进p1的num和score中
	//while循环,只要用户输入的学号不为0,程序继续
	struct Stu *head, *p1, *p2;
	p1 = p2 = (struct Stu *)malloc(LEN);
	printf("please input stu num:");
	scanf_s("%d", &p1->num);
	printf("please input stu score:");
	scanf_s("%lf", &p1->score);
	head = NULL;
	while (0 != p1->num)//如果输入的学号为0,程序结束停止接受用户输入新的学员信息
	{
		n++;
		if (1 == n)
		{
			//当n==1时。则说明是第一个学生的信息,把head指向第一个学生
			head = p1;
		}
		else
		{
			//已经是第二个学生和以后的学生信息了,就先把用户刚输入的信息放入p2的next
			p2->next = p1;
		}
		//把用户刚输入的信息p1的值赋值给p2
		p2 = p1;
		//p1从新再接收用户的输入
		p1 = (struct Stu *)malloc(LEN);
		printf("please input stu num:");
		scanf_s("%d", &p1->num);
		printf("please input stu score:");
		scanf_s("%lf", &p1->score);
	}
	//用户输入的学号为0,循环结束,则把当前最后的,也就是指向最后用户输入的信息的p2的next指向NULL,结束链表创建
	p2->next = NULL;
	//返回链表的头指针
	return head;

}

void print(struct Stu *head)
{
	struct Stu *p;
	p = head;
	if (NULL != head)
	{
		do 
		{
			printf("%d  %lf\n", p->num, p->score);
			p = p->next;
		} while (NULL != p);
	}
	printf("\n");
}

struct Stu *insert(struct Stu *head, struct Stu *insert)
{
	//定义三个指针,p指向传进来的原有链表的头地址,p1指向需要插入的链表头地址
	struct Stu *p, *p1, *p2;
	p = head;
	p1 = insert;
	p2 = NULL;

	//先判断需要插入的学生学号p1->num大于原有的链表头p->num的,并且p的next不等于NULL,也就是不是空链表
	while (p1->num > p->num && NULL != p->next)
	{
		p2 = p;
		p = p->next;
	}
	//要插入的学生学号p1->num小于等于原有的链表头p->num的,又分两种情况
	if (p1->num <= p->num)
	{
		//等于
		if (head = p)
		{
			head = p1;
		}
		//小于。也就是放入原有链表的最前面
		else
		{
			p2->next = p1;
		}
		p1->next = p;
	}
	else
	{
		//放入原有链表的最后面
		p->next = p1;
		p1->next = NULL;
	}
	return head;
}

 

链表的删除:

(删除比插入稍微简单点。只需要把要删除的前一个的.next指向需要删除的数据的.next指向的地址)

 

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define LEN sizeof(struct Stu)

struct Stu
{
	long num;
	double score;
	struct Stu *next;
};

//创建链表
struct Stu *create();
//打印链表
void print(struct Stu *head);
//删除链表里面指定的学号的数据
struct Stu *del(struct Stu *head, long num);

int n;

void main()
{

	//创建链表
	struct Stu *stu;
	long m;
	stu = create();
	//打印链表
	print(stu);


	//删除指定学号的链表,再次打印
	printf("please delete is num:");
	scanf_s("%d", &m);
	print(del(stu, m));

	printf("\n");
	system("pause");

}


//创建链表
struct Stu *create()
{
	struct Stu *head, *p1, *p2;
	p1 = p2 = (struct Stu *)malloc(LEN);

	printf("pleast is num:");
	scanf_s("%d", &p1->num);
	printf("please is score:");
	scanf_s("%lf", &p1->score);

	head = NULL;
	n = 0;

	while (0 != p1->num)
	{
		n++;
		if (1 == n)
		{
			head = p1;
		}
		else
		{ 
			p2->next = p1;
		}
		p2 = p1;
		p1 = (struct Stu *)malloc(LEN);
		printf("pleast is num:");
		scanf_s("%d", &p1->num);
		printf("please is score:");
		scanf_s("%lf", &p1->score);
	}
	p2->next = NULL;
	return head;
}
//打印链表
void print(struct Stu *head)
{
	struct Stu *p;
	p = head;
	if (NULL != head)
	{
		do
		{
			printf("%d   %lf\n", p->num, p->score);
			p = p->next;
		} while (NULL != p);
	}
	printf("\n");
}
//删除链表里面指定的学号的数据
struct Stu *del(struct Stu *head, long num)
{
	struct Stu *p1 ,*p;
	p = head;
	p1 = NULL;
	if (NULL == head)
	{
		goto End;
	}
	while(p->num != num && NULL != p->next)
	{
		p1 = p;          //在向后移的时候记录下来
		p = p->next;  //向后接着找
	}
	if (p->num == num)
	{
		if (p == head)
		{
			head = p->next;
		}
		else {
			p1->next = p->next;
		}
	}

End:
	return head;
	
}

 

 

 

 

  • 32
    点赞
  • 148
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值