C 语法 - 11_链表之静态链表和学生管理系统

 以下为 link.hpp 文件内容:

#ifndef __LINK_H__
#define __LINK_H__

//定义链表节点类型
typedef struct stu
{
	//数据域
	int num;
	char name[130];
	float score;

	//指针域
	struct stu* next;
}STU;

#endif

 以下为 link.cpp 文件内容:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "link.hpp"

//链表头部之前插入节点
void insert_link(STU** head, STU tmp)
{
	//为待插入的节点申请空间
	STU *pi = (STU*)calloc(1, sizeof(STU));	
	if(pi == NULL)
	{
		perror("calloc");  //打印错误信息
		exit(-1);           //结束进程
	}

	//给申请的结构体空间赋值
	*pi = tmp;
	pi->next = NULL;

	//判断链表是否存在
	if(*head == NULL)  //链表不存在
	{
		*head = pi;
	}
	else           //链表存在
	{
		pi->next = *head;
		*head = pi;
	}

}

#if 0
//链表尾部插入节点
STU* insert_link(STU* head, STU tmp)
{
	//为待插入的节点申请空间
	STU *pi = (STU*)calloc(1, sizeof(STU));	
	if(pi == NULL)
	{
		perror("calloc");  //打印错误信息
		exit(-1);           //结束进程
	}

	//给申请的结构体空间赋值
	*pi = tmp;
	pi->next = NULL;

	//判断链表是否存在
	if(head == NULL)  //链表不存在
	{
		head = pi;
	}
	else           //链表存在
	{
		//查找尾节点pr
		STU* pr = head;
		while(pr->next != NULL)
		{
			pr = pr->next;
		}

		pr->next = pi;
	}
	return head;

}

#endif

//链表有序插入节点,自动排序
STU* insert_link(STU* head, STU tmp)
{
	//为待插入的节点申请空间
	STU *pi = (STU*)calloc(1, sizeof(STU));	
	if(pi == NULL)
	{
		perror("calloc");  //打印错误信息
		exit(-1);           //结束进程
	}

	//给申请的结构体空间赋值
	*pi = tmp;
	pi->next = NULL;

	//判断链表是否存在
	if(head == NULL)  //链表不存在
	{
		head = pi;
	}
	else           //链表存在
	{
		//寻找插入点位置
		STU *pb = head;
		STU *pf = head;
		while(pb->num < pi->num && pb->next != NULL)
		{
			pf = pb;
			pb = pb->next;
		}

		if(pb->num >= pi->num)   //头部、中间插入
		{
			if(pb == head)     //头部插入
			{
				head = pi;
				pi->next = pb;
			}
			else         //中间插入
			{
				pf->next = pi;
				pi->next = pb;
			}
		}
		else        //尾部插入
		{
			pb->next = pi;
		}

	}
	return head;

}

//遍历节点
void print_link(STU *head)
{
	STU *p = head;

	if(p == NULL)
	{
		printf("链表不存在\n");
		return;
	}

	while(p != NULL)
	{
		printf("序号%d,名字%s,成绩%.2f\n", p->num, p->name, p->score);
		p = p->next;
	}

}

//查询链表指定结点
STU* search_link(STU *head, char* name)
{
	//判断链表是否存在
	if(head == NULL)
	{
		printf("链表不存在\n");
		return NULL;
	}
	else //链表存在
	{
		STU* pb = head;
		while(strcmp(pb->name, name) != 0 && pb->next != NULL)
		{
			pb = pb->next;
		}

		//找到链表
		if(strcmp(pb->name, name) == 0)
		{
			return pb;
		}
		else
		{
			printf("未找到相关数据\n");
			return NULL;
		}
	}

}

//删除链表指定节点
STU* delete_link(STU* head, int num)
{
	//判断链表是否存在
	if(head == NULL)
	{
		printf("链表不存在\n");
		return head;
	}
	else
	{
		//查找删除的节点
		STU *pd = head, *pf = head;
		while((pd->num != num) && (pd->next != NULL))
		{
			pf = pd;
			pd = pd->next;
		}

		if(pd->num == num)   //找到节点
		{
			//判断删除点的位置
			if(pd == head)             //删除头结点
			{
				head = pd->next;
			}
			else if(pd->next == NULL)  //删除尾节点
			{
				//pf->next = pd->next;
				pf->next = NULL;
			}
			else                       //删除中间节点
			{
				pf->next = pd->next;
			}

			free(pd);
			pd = NULL;
			printf("已成功删除 num = %d 的节点\n", num);
		}
		else                 //未找到
		{
			printf("未找到需要删除的节点\n");
		}
	}

	return head;

}

//释放链表
STU* free_link(STU* head)
{
	//判断链表是否存在
	if(head == NULL)
	{
		printf("链表不存在\n");
	}
	else
	{
		STU *pd = head;
		while(pd != NULL)
		{
			head = pd->next;
			free(pd);
			pd = head;
		}
	}
	return NULL;

}

//翻转链表
STU* reverse_link(STU* head)
{
	//判断链表是否存在
	if(head == NULL)
	{
		printf("链表不存在\n");
	}
	else
	{
		STU* pb = head;
		STU* pf = pb->next;    //保存下一个节点
		pb->next = NULL;

		while(pf != NULL)      //判断下一个节点是否存在
		{
			pb = pf;           //当前节点移动到下一个节点
			pf = pb->next;     //再保存当前节点的下一个节点
			pb->next = head;   //当前节点指向头节点(上一个节点)
			head = pb;         //头节点移动到当前节点
		}
		printf("链表翻转成功\n");
	}
	return head;

}

//链表排序
void sort_link(STU* head)
{
	//判断链表是否存在
	if(head == NULL)
	{
		printf("链表不存在\n");
	}
	else
	{
		STU *p_i = head;           //for (int i=0; i<n-1; i++)
		while (p_i->next != NULL)  //i<n-1
		{
			STU *p_min = p_i;     //int min = i;

			STU *p_j = p_min->next;      //for (int j=min+1; j<n; j++)
			while (p_j != NULL)          //j<n
			{
				if (p_min->score<p_j->score)  //if(arr[min]<arr[j])
				{
					p_min = p_j;        //min = j;
				}
				p_j = p_j->next;       //j++
			}

			if (p_i != p_min)       //if (i != min)
			{
				//交换数据
				STU tmp = *p_i;
				*p_i = *p_min;
				*p_min = tmp;

				tmp.next = p_i->next;
				p_i->next = p_min->next;
				p_min->next = tmp.next;
			}
			p_i = p_i->next;       //i++
		}
	}

	return;

}

 以下为 main.cpp 文件内容:



#include <stdio.h>
#include <string.h>

#include "link.hpp"

//静态链表
void test01()
{
	struct STU1
	{
		//数据域
		int num;
		char name[32];

		//指针域
		struct STU1* next;
	};

	//创建链表节点
	struct STU1 bob = {10, "bob", NULL};
	struct STU1 lucy = {20, "lucy", NULL};
	struct STU1 tom = {30, "tom", NULL};
	struct STU1 dema = {40, "德玛", NULL};
	struct STU1 wuji = {50, "无极", NULL};

	//链接链表节点
	struct STU1* head = &bob;
	bob.next = &lucy;
	lucy.next = &tom;
	tom.next = &dema;
	dema.next = &wuji;
	wuji.next = NULL;

	//遍历链表节点
	struct STU1* p = head;
	while(p != NULL)
	{
		printf("学号 %d,姓名:%s\n", p->num, p->name);

		p = p->next;
	}

}


STU *HEAD = NULL;  //定义头结点

void insert_link(STU** head, STU tmp);
STU* insert_link(STU* head, STU tmp);
void print_link(STU *head);
STU* search_link(STU *head, char* name);
STU* delete_link(STU* head, int num);
STU* free_link(STU* head);
STU* reverse_link(STU* head);
void sort_link(STU* head);

void help(void)
{
	printf("*****************************\n");
	printf("*help:帮助信息             *\n");
	printf("*insert:插入链表节点       *\n");
	printf("*print:遍历链表节点        *\n");
	printf("*search:查询链表某个节点   *\n");
	printf("*delete:删除链表某个节点   *\n");
	printf("*free:释放整个链表         *\n");
	printf("*quit:退出程序             *\n");
	printf("*reverse:翻转链表          *\n");
	printf("*sort:链表排序             *\n");
	printf("*****************************\n");

}

int main(int argc, char const* argv[])
{
	help();

	while(1)
	{
		char cmd[130] = "";
		printf("请输入操作命令\n");
		scanf("%s", cmd);

		if(strcmp(cmd, "help") == 0)
		{
			help();
		}
		else if(strcmp(cmd, "insert") == 0)
		{
			printf("请输入需要插入的学生信息 num name score :");

			STU tmp;
			scanf("%d %s %f", &tmp.num, tmp.name, &tmp.score);

			//insert_link(&HEAD, tmp);
			HEAD = insert_link(HEAD, tmp);

		}
		else if(strcmp(cmd, "print") == 0)
		{
			print_link(HEAD);
		}
		else if(strcmp(cmd, "search") == 0)
		{
			printf("请输入要查找的姓名:");
			char name[136] = "";
			scanf("%s", name);

			STU* ret = search_link(HEAD, name);
			if(ret != NULL)
			{
				printf("查询的结果: %d %s %.2f\n", ret->num, ret->name, ret->score);
			}
		}
		else if(strcmp(cmd, "delete") == 0)
		{
			printf("请输入要删除的学号:");

			int num = 0;
			scanf("%d", &num);

			HEAD = delete_link(HEAD, num);
		}
		else if(strcmp(cmd, "free") == 0)
		{
			HEAD = free_link(HEAD);
		}
		else if(strcmp(cmd, "quit") == 0)
		{
			HEAD = free_link(HEAD);
			break;
		}
		else if(strcmp(cmd, "reverse") == 0)
		{
			HEAD = reverse_link(HEAD);
		}
		else if(strcmp(cmd, "sort") == 0)
		{
			sort_link(HEAD);
		}

	}

	return 0;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值