代码
app.c
#include "app.h"
#include <stdlib.h>
union person{ //定义一个共用体,保存常用的name及id,来节省空间
char name[20];
int id;
};
union person stu; //共用体变量stu
//申请新节点的函数
Node * Create_Node(void)
{
Node * new = (Node *)malloc(sizeof(Node)); //定义Node*类型的指针,接收所申请节点空间的地址
if(new == NULL)
{
printf("申请空间失败!\n");
return NULL;
}
memset(new,0, sizeof(Node)); //对申请的节点初始化,置0
return new; //返回申请节点空间的地址
}
void input(Node * head) //新增全部信息 //值传参
{
int num=0;
printf("请输入你要创建信息的个数:\n");
scanf("%d",&num);
while(getchar()!= '\n');
for(int i=num;i>0;i--)
{
//新增信息
Node * NewNode = Create_Node();//申请新节点
if(NewNode == NULL)
{
printf("申请新节点失败!\n");
return ;
}
//尾插法(输出正序)
/*
Node * p =head;
while(p->next!=NULL) //确定p为最后一个节点
{
p=p->next;
}
p->next=NewNode; //新节点放在最后
*/
//头插法(输出倒序)
Node * p =head;
NewNode->next= p->next; //先断开,再连接头节点 // 指针域 = 常量地址
p->next= NewNode; //连接头节点
printf("请输入姓名:\n");
scanf("%s",NewNode->inf.name);
while(getchar()!= '\n');
printf("请输入id:\n");
scanf("%d",&NewNode->inf.id);
while(getchar()!= '\n');
}
}
void output(Node * head) //输出全部信息
{
Node * p= head;
if(p->next == NULL) //如果该连表只有一个头节点
{
printf("该连表为空!\n");
return ;
}
printf("下面输出所与人的信息:\n");
printf("*****************begin********************\n");
printf("姓名\tid\n");
while(p->next!=NULL)
{
p=p->next; //因为头节点一般无值,所以让其指向下一个节点,输出其中的值
printf("%s\t%d\n",p->inf.name,p->inf.id);
}
printf("******************end*********************\n");
}
Node * search(Node * head) //查询信息
{
Node * p= head;
if(p->next == NULL) //如果该连表只有一个头节点
{
printf("该连表为空!\n");
return NULL;
}
char val=0;
printf("输入你要查询的条件:1.姓名、2.学号、3.退出\n");
scanf("%c",&val);
while(getchar()!='\n');
switch(val)
{
case '1':
printf("请输入姓名:\n");
scanf("%s",stu.name);
while(getchar()!='\n');
while(p->next!=NULL)
{
p=p->next;
if( strcmp(p->inf.name,stu.name)==0 )
return p;
}
break;
case '2':
printf("请输入学号:\n");
scanf("%d",&stu.id);
while(getchar()!='\n');
while(p->next!=NULL)
{
p=p->next;
if(p->inf.id == stu.id)
return p;
}
break;
case '3':
return NULL;
default:
printf("input err\n");
break;
}
}
void delete(Node * head) //信息删除
{
Node * p = head;
Node * tmp = NULL;
if(p->next == NULL)
{
printf("该链表为空!\n");
return ;
}
printf("输入学号:\n");
scanf("%d",&stu.id);
while(getchar()!='\n');
while(p->next != NULL) // 判断当前节点后面是否有节点
{
if(p->next->inf.id == stu.id) // 比较当前节点p的,下一节点的信息
{
printf("这个人的信息是:\n");
printf("%s %d\n",p->next->inf.name,p->next->inf.id);
tmp = p->next; //保存当前节点的下一节点的地址
p->next = tmp->next; //将当前节点的,下一节点的,下一个节点的地址,给到当前节点的指针域
free(tmp); //释放符合信息的地址空间 //即:使当前节点的指针域,指向下一个节点的下一个节点(删除当前节点的下一个节点)
break;
}
p=p->next; //让指针往下走
}
output(head);
}
void revise(Node * head) //信息修改
{
Node * p = search(head); //定义指针,接收search()函数返回的查询到的数据的地址
printf("下面重新输入这个人的: 姓名、学号:\n");
scanf("%s %d",p->inf.name,&p->inf.id); //重新在该位置输入信息,将原信息覆盖
while(getchar()!='\n');
output(head);
}
void sort(Node * head) //信息排序
{
printf("下面按id,从小到大排序\n");
Node * p= head;
Node * q= head;
INF tmp = {0}; //保存相应节点数据域中的信息
while(p->next!=NULL)
{
q=head; //使q每次循环时,都指向头节点,即下面的每次循环都从链表的头开始,把值全部比较一遍
while(q->next->next!=NULL)
{
if(q->next->inf.id > q->next->next->inf.id)
{
tmp = q->next->inf;
q->next->inf = q->next->next->inf;
q->next->next->inf = tmp;
}
q=q->next;
}
p=p->next; //p指针往下走
}
output(head);
}
void save(Node * head) //保存信息于一个excel文件中
{
FILE * fp=NULL;
fp = fopen("stu.xlsx","w+");
if(fp == NULL)
{
printf("打开文件失败!\n");
return ;
}
Node * p= head;
if(p->next==NULL)
{
printf("该链表为空!\n");
return ;
}
fprintf(fp,"姓名\t学号\n");
while(p->next!=NULL)
{
p= p->next;
fprintf(fp,"%s\t%d\n",p->inf.name,p->inf.id);
}
fclose(fp);
}
void read_t(Node * head) //将存储在 stu.xlsx 文件中的学生信息读出
{
Node * p= head;
FILE * fp=NULL;
fp = fopen("stu.xlsx","r");
if(fp == NULL)
{
printf("打开文件失败!\n");
return ;
}
fscanf(fp,"姓名\t学号\n"); //先读取头,让光标后移
while(feof(fp)==0)
{
Node * new= Create_Node(); //申请新节点
fscanf(fp,"%s\t%d\n",new->inf.name,&new->inf.id);
//头插法建立链表
new->next= p->next;
p->next= new;
}
fclose(fp);
output(head);
}
void clear_t(Node * head) //清空链表
{
Node *p=head;
if(p->next==NULL)
{
printf("该链表为空!\n");
return ;
}
while(p->next!=NULL)
{
Node * tmp= p->next;
p->next=p->next->next;
free(tmp);
}
printf("清除链表成功!\n");
}
app.h
#ifndef _APP_H_
#define _APP_H_
#include <stdio.h>
#include <string.h>
//定义节点类型
typedef struct info{
char name[20];
int id;
}INF;
typedef struct node{
INF inf;
struct node * next;
}Node;
/*
//构建节点的内容
typedef struct node{ //节点
struct info{ //数据域
char name[20];
int id;
} inf;
struct node * next; //指针域
}Node; //节点名称
*/
Node * Create_Node(void);
void input(Node * head);
void output(Node * head);
Node * search(Node * head);
void delete(Node * head);
void revise(Node * head); //信息修改
void sort(Node * head);
void save(Node * head);
void read_t(Node * head); //将存储在 stu.xlsx 文件中的学生信息读出
void clear_t(Node * head);
#endif
mian.c
#include "app.h"
int main()
{
//定义头指针指向头节点
Node * head=NULL; // 头指针head置0
head=Create_Node(); // 申请头节点
if(head == NULL)
{
printf("申请头节点失败!\n");
return 0;
}
Node *p= NULL; //定义Node *类型的指针,接受search()的返回值
while(1)
{
char val=0;
printf("输入:0.退出、1.信息输入、2.信息查找、3.删除、\n\t4、修改、5、排序、6.信息输出、7.保存、8.提取信息、9.清除链表\n");
scanf("%c",&val);
while(getchar()!= '\n');
switch(val)
{
case '0':
return 0;
case '1':
input(head); //1.信息输入
break;
case '2':
p= search(head);//2.信息查找
printf("%s\t%d\n",p->inf.name,p->inf.id);
break;
case '3':
delete(head); //3.删除
break;
case '4':
revise(head); //4、修改
break;
case '5':
sort(head); //5、排序
break;
case '6':
output(head); //6.信息输出
break;
case '7':
save(head); //7.保存信息
break;
case '8':
read_t(head); //8.加载信息
break;
case '9':
clear_t(head); //9.清除链表
break;
default:
printf("input err\n");
break;
}
}
return 0;
}