现有学生的信息需要存储,学生信息包括:姓名、年龄、分数,利用单向表实现以下功能:
-
创建头结点
-
创建普通结点
-
单链表头插
-
单链表尾插
-
单链表的遍历
-
单链表的头删
-
单链表尾删
-
单链表按位置插入
-
单链表按位置删除
-
单链表按位置修改
-
单链表按位置查找
-
单链表按元素查找
-
单链表按元素修改
-
单链表按元素删除
-
单链表逆置
-
按成绩冒泡排序
-
单链表的释放
main.c
#include "main.h"
int main(int argc, char const *argv[])
{
int n;
linklist L = Create_Head();
printf("请输入学生个数:");
scanf("%d",&n);
datatype e;
printf("\n<-------------------------学生信息录入------------------------->\n\n");
#if 0
for (size_t i = 0; i < n; i++)
{
printf("请输入第%ld名学生的姓名:",i+1);
scanf("%s",e.name);
printf("请输入第%ld名学生的年龄:",i+1);
scanf("%d",&e.age);
printf("请输入第%ld名学生的分数:",i+1);
scanf("%lf",&e.score);
Insert_Head(L,e);
printf("\n");
}
#else
for (size_t i = 0; i < n; i++)
{
printf("请输入第%ld名学生的姓名:",i+1);
scanf("%s",e.name);
printf("请输入第%ld名学生的年龄:",i+1);
scanf("%d",&e.age);
printf("请输入第%ld名学生的分数:",i+1);
scanf("%lf",&e.score);
Insert_Rear(L,e);
printf("\n");
}
#endif
OutputList(L);
//链表头删
printf("\n<-------------------------学生信息头删------------------------->\n\n");
Delete_Head(L);
OutputList(L);
//链表尾删
printf("\n<-------------------------学生信息尾删------------------------->\n\n");
Delete_Rear(L);
OutputList(L);
//单链表按位置插入
printf("\n<-------------------------学生信息按位置插入------------------------->\n\n");
int pos;
printf("请输入插入的位置:");
scanf("%d",&pos);
if(pos>=1 && pos<=L->len+1)
{
printf("请输入插入的学生的姓名:");
scanf("%s",e.name);
printf("请输入插入的学生的年龄:");
scanf("%d",&e.age);
printf("请输入插入的学生的分数:");
scanf("%lf",&e.score);
Insert_Position(L,pos,e);
OutputList(L);
}
else
{
printf("\n插入位置不合法,操作失败!\n\n");
}
//单链表按位置删除
printf("\n<-------------------------学生信息按位置删除------------------------->\n\n");
printf("请输入删除的位置:");
scanf("%d",&pos);
Delete_Position(L,pos);
OutputList(L);
//单链表按位置修改
printf("\n<-------------------------学生信息按位置修改------------------------->\n\n");
printf("请输入修改的位置:");
scanf("%d",&pos);
if(pos>=1 && pos<=L->len)
{
printf("请输入修改后的学生的姓名:");
scanf("%s",e.name);
printf("请输入修改后的学生的年龄:");
scanf("%d",&e.age);
printf("请输入修改后的学生的分数:");
scanf("%lf",&e.score);
Updata_Position(L,pos,e);
OutputList(L);
}
else
{
printf("\n修改位置不合法,操作失败!\n\n");
}
//单链表按位置查找
printf("\n<-------------------------学生信息按位置查找------------------------->\n\n");
printf("请输入查找的位置:");
scanf("%d",&pos);
Search_Position(L,pos);
//单链表按元素查找
printf("\n<-------------------------学生信息按元素查找------------------------->\n\n");
printf("请输入查找的学生的姓名:");
scanf("%s",e.name);
printf("请输入查找的学生的年龄:");
scanf("%d",&e.age);
printf("请输入查找的学生的分数:");
scanf("%lf",&e.score);
printf("\n您所查询的学生在位置:%d\n\n",Search_Data(L,e));
OutputList(L);
//单链表按元素修改
datatype key;
printf("\n<-------------------------学生信息按元素修改------------------------->\n\n");
printf("请输入修改前的学生的姓名:");
scanf("%s",key.name);
printf("请输入修改前的学生的年龄:");
scanf("%d",&key.age);
printf("请输入修改前的学生的分数:");
scanf("%lf",&key.score);
printf("\n\n");
printf("请输入修改后的学生的姓名:");
scanf("%s",e.name);
printf("请输入修改后的学生的年龄:");
scanf("%d",&e.age);
printf("请输入修改后的学生的分数:");
scanf("%lf",&e.score);
Updata_Data(L,key,e);
OutputList(L);
//单链表按元素删除
printf("\n<-------------------------学生信息按元素删除------------------------->\n\n");
printf("请输入删除的学生的姓名:");
scanf("%s",e.name);
printf("请输入删除的学生的年龄:");
scanf("%d",&e.age);
printf("请输入删除的学生的分数:");
scanf("%lf",&e.score);
Delete_Data(L,e);
OutputList(L);
//单链表逆置
printf("\n<-------------------------学生信息逆置------------------------->\n\n");
printf("逆置前的学生信息如下所示:\n");
OutputList(L);
printf("逆置后的学生信息如下所示:\n");
Inversion_Link(L);
OutputList(L);
//冒泡排序
printf("\n<-------------------------学生信息按成绩排序------------------------->\n\n");
printf("排序前的学生信息如下所示:\n");
OutputList(L);
printf("排序后的学生信息如下所示:\n");
BubbleSort(L);
OutputList(L);
//链表空间释放
L = free_space(L);
return 0;
}
main.h
#ifndef __MAIN_H
#define __MAIN_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//学生信息结构体
typedef struct
{
char name[20]; //学生信息
int age; //学生年龄
double score; //学生分数
}Student;
typedef Student datatype;
typedef struct Node
{
//数据域
union
{
int len; //头结点数据域
datatype data;
};
//指针域
struct Node *next; //指向下一个结点
}*linklist;
linklist Create_Head(); //创建头结点
linklist Create_Node(); //创建普通结点
int Insert_Head(linklist L,datatype e); //单链表头插
int Insert_Rear(linklist L,datatype e); //单链表尾插
void OutputList(linklist L); //单链表的遍历
int Delete_Head(linklist L); //单链表的头删
int Delete_Rear(linklist L); //单链表尾删
int Insert_Position(linklist L,int pos,datatype e); //单链表按位置插入
int Delete_Position(linklist L,int pos); //单链表按位置删除
int Updata_Position(linklist L,int pos,datatype e); //单链表按位置修改
int Search_Position(linklist L,int pos); //单链表按位置查找
int Search_Data(linklist L,datatype e); //单链表按元素查找
int Updata_Data(linklist L,datatype key,datatype e); //单链表按元素修改
int Delete_Data(linklist L,datatype e); //单链表按元素删除
int Inversion_Link(linklist L); //单链表逆置
void BubbleSort(linklist L); //冒泡排序
linklist free_space(linklist L); //单链表的释放
#endif // !__MAIN_H
linklist.c
#include "main.h"
/**
* @brief 创建头结点
*
* @return linklist
*/
linklist Create_Head()
{
linklist L = (linklist)malloc(sizeof(struct Node));
if (L == NULL)
return NULL;
//数据域
L->len = 0;
//指针域
L->next = NULL;
return L;
}
/**
* @brief 创建普通结点
*
* @return linklist
*/
linklist Create_Node()
{
linklist p = (linklist)malloc(sizeof(struct Node));
if (p == NULL)
return NULL;
//数据域
strcpy(p->data.name,"\0");
p->data.age = 0;
p->data.score = 0;
//指针域
p->next = NULL;
return p;
}
/**
* @brief 单链表头插
*
* @param L 单链表
* @param e 插入的学生信息
* @return int 成功返回0,失败返回-1
*/
int Insert_Head(linklist L,datatype e)
{
if (L == NULL)
{
printf("\n链表不存在,数据头插失败!\n\n");
return -1;
}
linklist p = Create_Node();
if (p == NULL)
return -1;
//数据域
p->data = e;
//指针域
p->next = L->next;
L->next = p;
L->len++;
return 0;
}
/**
* @brief 单链表尾插
*
* @param L
* @param e 学生信息
* @return int 成功返回0,失败返回-1
*/
int Insert_Rear(linklist L,datatype e)
{
if (L == NULL)
{
printf("\n链表不存在,数据尾插失败!\n\n");
return -1;
}
linklist p = Create_Node();
if (p == NULL)
return -1;
linklist q = L;
for (size_t i = 1; i <= L->len; i++)
{
q = q->next;
}
//指针域
p->next = q->next;
q->next = p;
//数据域
p->data = e;
L->len++;
return 0;
}
/**
* @brief 链表遍历输出
*
* @param L
*/
void OutputList(linklist L)
{
if (L == NULL || L->len == 0)
{
printf("\n数据元素不存在,遍历失败!\n\n");
return;
}
linklist p = L;
for (size_t i = 1; i <= L->len; i++)
{
p = p->next;
printf("\n姓名\t\t年龄\t\t分数\n");
printf("\n%s\t\t%d\t\t%.1lf\n",p->data.name,p->data.age,p->data.score);
}
}
/**
* @brief 单链表头删
*
* @param L
* @return int 成功返回0,失败返回-1
*/
int Delete_Head(linklist L)
{
if (L == NULL || L->len == 0)
{
printf("\n数据元素不存在,头删失败!\n\n");
return -1;
}
linklist q = L->next;
L->next = q->next;
free(q);
q = NULL;
L->len--;
return 0;
}
/**
* @brief 单链表尾删
*
* @param L
* @return int 成功返回0,失败返回-1
*/
int Delete_Rear(linklist L)
{
if (L == NULL || L->len == 0)
{
printf("\n数据元素不存在,尾删失败!\n\n");
return -1;
}
linklist p = L;
for (size_t i = 1; i <= L->len-1; i++)
{
p = p->next;
}
free(p->next);
p->next = L;
L->len--;
return 0;
}
/**
* @brief 单链表按位置插入
*
* @param L 单链表
* @param pos 插入的位置
* @param e 学生信息
* @return int 成功返回0,失败返回-1
*/
int Insert_Position(linklist L,int pos,datatype e)
{
if (L == NULL || L->len == 0 || pos < 1 || pos > L->len+1)
{
printf("\n单链表按位置插入失败!\n\n");
return -1;
}
linklist p = Create_Node();
if (p == NULL)
return -1;
linklist q = L;
for (size_t i = 1; i <= pos-1; i++)
{
q = q->next;
}
//数据域
p->data = e;
//指针域
p->next = q->next;
q->next = p;
L->len++;
return 0;
}
/**
* @brief 单链表按位置删除
*
* @param L 单链表
* @param pos 删除的位置
* @return int 成功返回0,失败返回-1
*/
int Delete_Position(linklist L,int pos)
{
if (L == NULL || L->len == 0 || pos < 1 || pos > L->len)
{
printf("\n单链表按位置删除失败!\n\n");
return -1;
}
linklist p = L;
for (size_t i = 1; i <= pos-1; i++)
{
p = p->next;
}
linklist q = p->next;
p->next = q->next;
free(q);
q = NULL;
L->len--;
return 0;
}
/**
* @brief 单链表按位置修改
*
* @param L 单链表
* @param pos 修改的位置
* @param e 学生信息
* @return int 成功返回0,失败返回-1
*/
int Updata_Position(linklist L,int pos,datatype e)
{
if (L == NULL || L->len == 0 || pos < 1 || pos > L->len)
{
printf("\n单链表按位置修改失败!\n\n");
return -1;
}
linklist p = L;
for (size_t i = 1; i <= pos; i++)
{
p = p->next;
}
p->data = e;
return 0;
}
/**
* @brief 单链表按位置查找
*
* @param L
* @param pos 查找的位置
* @return int 成功返回0,失败返回-1
*/
int Search_Position(linklist L,int pos)
{
if (L == NULL || L->len == 0 || pos < 1 || pos > L->len)
{
printf("\n单链表按位置查找失败!\n\n");
return -1;
}
linklist p = L;
for (size_t i = 1; i <= pos; i++)
{
p = p->next;
}
printf("您所查询的学生信息如下:\n");
printf("\n姓名\t\t年龄\t\t分数\n");
printf("\n%s\t\t%d\t\t%.1lf\n",p->data.name,p->data.age,p->data.score);
return 0;
}
/**
* @brief 单链表按元素查找
*
* @param L 单链表
* @param e 学生信息
* @return int 成功返回位置,失败返回-1
*/
int Search_Data(linklist L,datatype e)
{
if (L == NULL || L->len == 0)
{
printf("\n单链表按元素查找失败!\n\n");
return -1;
}
linklist p = L;
for (int i = 1; i <= L->len; i++)
{
p = p->next;
if (strcmp(p->data.name,e.name)==0 && p->data.age==e.age && p->data.score==e.score)
{
return i;
}
}
return -1;
}
/**
* @brief 单链表按元素修改
*
* @param L
* @param key 修改前的元素
* @param e 修改后的元素
* @return int 成功返回0,失败返回-1
*/
int Updata_Data(linklist L,datatype key,datatype e)
{
int pos = Search_Data(L,key);
if (pos == -1)
{
printf("\n单链表按元素修改失败!\n\n");
return -1;
}
Updata_Position(L,pos,e);
return 0;
}
/**
* @brief 单链表按元素删除
*
* @param L 单链表
* @param e 删除的学生信息
* @return int 成功返回0,失败返回-1
*/
int Delete_Data(linklist L,datatype e)
{
int pos = Search_Data(L,e);
if (pos == -1)
{
printf("\n单链表按元素删除失败!\n\n");
return -1;
}
Delete_Position(L,pos);
return 0;
}
/**
* @brief 单链表逆置
*
* @param L
* @return int 成功返回0,失败返回-1
*/
int Inversion_Link(linklist L)
{
if (L == NULL || L->len == 0)
{
printf("\n单项链表逆置失败!\n\n");
return -1;
}
linklist p = L->next;
L->next = NULL;
for (size_t i = 1; i <= L->len; i++)
{
linklist t = p->next;
p->next = L->next;
L->next = p;
p = t;
}
return 0;
}
/**
* @brief 按成绩冒泡排序
*
* @param L
*/
void BubbleSort(linklist L)
{
for (size_t i = 1; i < L->len; i++)
{
linklist p = L;
int flag = 0;
for (size_t j = 0; j < L->len-i; j++)
{
p = p->next;
if (p->data.score < p->next->data.score)
{
datatype temp = p->data;
p->data = p->next->data;
p->next->data = temp;
flag = 1;
}
}
if (flag == 0)
break;
}
}
/**
* @brief 链表空间释放
*
* @param L
* @return linklist
*/
linklist free_space(linklist L)
{
if (L == NULL)
return NULL;
int count = L->len;
for (size_t i = 0; i < count; i++)
{
Delete_Head(L);
}
free(L);
L = NULL;
return L;
}