链表实现学生信息存储(01)

#include
#include
#define PT "学号:%ld 姓名:%-10s 性别:%c\n",p->num,p->name,p->sex
#define N sizeof(struct student)
struct student
{
	long num;
	char name[11];
	char sex;
	struct student *next;//指向本结构体体类型的指针类型
};

struct student *creat(struct student *head);//初始化链表/创建链表
int listlength(struct student *head);//计算学生个数
struct student *listinsert(struct student *head);//插入一个结点
struct student *listdelete(struct student *head);//删除一个指定结点
void listget(struct student *head);//查询指定的数据元素
void print(struct student *p);//输出全班学生信息

int main()
{
	int n,number=0;//number为学生个数,m为中间变量,判断是否插入正确
	struct student *head=NULL;//head指针指向链表
	struct student *p=NULL;
    printf("创建链表\n");
    head=creat(head);//将main函数中的head指针传入创建链表中
    printf("全班同学的名单为:\n");
	print(head);//输出创建的链表
	//输出表头
	printf("*********学生表*********\n");
	printf("------链表的管理--------\n");
	printf("1--求当前学生数量\n");
	printf("2--插入一个学生信息\n");
	printf("3--删除一个学生信息\n");
	printf("4--查询一个学生信息\n");
	printf("0--结束运行\n");
	printf("========================\n");
	printf("请输入编号(0-4)\n");
	//表头输入结束
	scanf("%d",&n);
	while(!(n==0||n==1||n==2||n==3||n==4))
	{
		printf("输入的编号错误,请重新输入(0-4)\n");
		scanf("%d",&n);
	}
	if(n==0)//0--结束
		printf("感谢使用!\n");
	else
	{
       switch(n)
		{
		     case 1://1--求当前学生数量
				 number=listlength(head);
				 printf("学生个数为%d\n",number);
				 break;
			 case 2://2--插入一个学生信息
				 head=listinsert(head);
				 print(head);
				 break;
			 case 3://3--删除一个学生信息
				 head=listdelete(head);
				 print(head);
				 break;
			 case 4://4--查询一个学生信息
				 listget(head);
				 break;
        }//分支选择结构结束
    }//else的结尾
    return 0;
}//mian函数的结尾

struct student * creat(struct student *head)//初始化链表/创建链表
{
	struct student *p1,*p2;//head为头指针  P1每次都指向新申请的结点  p2每次指向申请的新结点的前一个结点,以此来建立联系,保证链表连接
	int i=0;//给全局变量i赋值为1,用来统计全班人数
	printf("请输入学号  姓名  性别(男生输入M,女生输入W)\n");
	printf("(若输入学号为-1则停止输入)\n");
	while(1)
	{
		if((p1=(struct student *)malloc(N))==NULL)//申请动态内存分配
		   printf("申请内存失败!\n");
		p1->next=NULL;//先使得指针域初始化为null
		scanf("%ld %s %c",&p1->num,p1->name,&p1->sex);//输入学生信息
		i++;//记录全班人数变化
		if(p1->num==-1)
		   break;//结束输入
		if(i==1)//当第一个学生的信息存在后
		   head=p2=p1;//使得head指向第一个结点,p2也指向第一个结点
		else
		   p2->next=p1;//将新申请的结点与链表进行连接
		p2=p1;//如果储存完第一个学生的信息,执行该语句,使得p2每次指向申请的新结点的前一个结点
	}
	return head;//返回创建的链表
}

void print(struct student *head)//输出全班学生信息
{
	struct student *p=head;//传入的形参head指向已创建链表的第一个结点
	while(p!=NULL)
	{
		printf("学号:%ld 姓名:%-10s 性别:%c\n",p->num,p->name,p->sex);
		p=p->next;//遍历链表,直至最后一个结点
	}
}

int listlength(struct student* head)//求当前元素个数
{

	int size=1;
	struct student* p=head;
	while(p->next!=NULL)
	{
		p=p->next;
		size++;
	}
	return size;
}

struct student *listinsert(struct student *head)//插入一个结点
{
	int i,j=1;
	struct student *q,*p=head;//p先初始化为head,使它指向链表
	printf("请输入一个插入位置\n");
	scanf("%d",&i);
	q=(struct student *)malloc(N);
	if((q=(struct student *)malloc(N))==NULL)//申请动态内存,并使得q指向该结点
	   printf("申请内存失败!\n");
	printf("请输入要插入的学生信息:学号,姓名,性别\n");
	scanf("%ld %s %c",&q->num,q->name,&q->sex);
	while( p->next!=NULL && j<i-1 )//遍历链表,查找要插入的位置,找到要插入位置的前一个结点,并使p指向它,循环次数为i-1
	{
		p=p->next;
		j++;
	}
	if(j!=i-1)
	{
		printf("插入位置参数错!\n");
		exit(0);
	}

	//正确的找到了插入的位置再连接前面
	q->next=p->next;//先连接后面
	p->next=q;//再连接前面
	return head;//结点已经插入链表,原始链表发生变化,变成新链表,返回指向新链表的指针
}

struct student *listdelete(struct student *head)//删除一个结点
{
	struct student *s,*p=head;//s用来接收删除的结点 p用来指向传入的形参head,也就是p一开始指向链表第一个结点
	int j=1,i;
	printf("请输入需要删除的结点位置:\n");
	scanf("%d",&i);
	while(p->next!=NULL && p->next->next!=NULL && j<i-i)//遍历链表,查找要插入的位置,找到要插入位置的前一个结点,并使p指向它,循环次数为i-1
	{
		p=p->next;
		j++;
	}
	if(j!=i-1)
		printf("删除位置出错!");
	s=p->next;//s接受要删除的结点
	p->next=p->next->next;//删除结点
	free(s);//释放内存
	return head;
}

void listget(struct student *head)//查询相应的数据元素
{

	int j=1,i;
	struct student *p=head,*s;//s用来指向要查询的学生信息
	printf("请输入要查询的数据元素的标号:\n");
	scanf("%d",&i);
	while(p->next!=NULL && j<i-1)//遍历链表,循环次数为i
	{
		p=p->next;
		j++;
	}
	if(j!=i-1)
	{
		printf("取元素的位置参数错!");
		exit(0);
	}
	s=p->next;
	s->next=NULL;
	printf("学号:%ld 姓名:%-10s 性别:%c\n",s->num,s->name,s->sex);
}


![在这里插入图片描述](https://img-blog.csdnimg.cn/20191206200817153.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h1ZXpoZV9fX19f,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191206200524866.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h1ZXpoZV9fX19f,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191206200825889.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h1ZXpoZV9fX19f,size_16,color_FFFFFF,t_70)

你可能感兴趣的:(数据结构C语言)