//============================================================================================
//程序名称: 链表操作
//功能描述: 写若干函数,可以实现创建链表,删除,增加,查找,打印等功能
//组成文件: main.c stdio.h stdlib.h
//子函数 : LIST *creat(void); void prtlist(LIST*);
// void search(LIST*); void emptylist(LIST*);
// LIST *applynode(void); LIST * addnode(LIST * hds, LIST *pinsert);
// LIST * deletenode(LIST * hds); void list_wr_file(LIST *hds);
// void display(void); void FucSel(void);
// void list_rd_file(void); unsigned int list_node_count(const LIST *hds)
//============================================================================================
#include <stdio.h>
#include <stdlib.h>
//定义的结点
typedef struct stu
{
int num;
int age;
struct stu *next;
}LIST;
//函数原型
LIST *creat(void); //创建函数
void prtlist(LIST *); //打印函数
void search(LIST *); //搜索函数
void emptylist(LIST *hds); //释放链表
LIST * applynode(void); //申请结点
LIST * addnode(LIST * hds, LIST *pinsert); //增加结点
LIST * deletenode(LIST * hds); //删除结点
unsigned int list_node_count(LIST *hds); //结点统计
void list_wr_file(LIST *hds); //写入文件
void list_rd_file(void); //从文件读
void sort_list(LIST *hds); //链表排序
void display(void); //菜单显示
void FucSel(void); //功能选择
//系统退出标志
char Flag;
/*
*主函数
*/
int main(void)
{
while(1)
{
display(); //菜单显示
FucSel(); //功能选择
if(Flag) //退出系统
break;
}
return 0;
}
/*
*创建链表
*/
LIST *creat()
{
LIST *head = NULL;
LIST *prev, *current;
char index;
int node;
printf("Do you want to create how many nodes?\n");
printf("Please input node's number: ");
while(1 != scanf("%d", &node))
getchar(); //创建node的个数
for(index = 0; index < node; index++)
{
current = (LIST *)malloc(sizeof(LIST)); //分配新的node地址
if(head == NULL)
head = current; //空表建立的时候
else
prev->next = current; //非空表
current->next = NULL;
scanf("%d %d", ¤t->num, ¤t->age);
prev = current; //更新老node的地址
}
return head;
}
/*
*打印函数
*/
void prtlist(LIST *hds)
{
char index = 0;
printf(" the list's all infor as following: \n");
if(hds == NULL) //链表为空提示信息
printf(" Oh,my god!this is empty list\n");
while(hds != NULL) //从head开始打印
{
index++;
printf(" the NO.%d : num is %d age is %d\n", index, hds->num, hds->age);
hds = hds->next;
}
printf("\n");
}
/*
*查找函数
*/
void search(LIST *hds)
{
int innum;
printf(" Do you want to search?");
printf(" Please input your num : ");
scanf("%d", &innum); //输入要查找的num
if(hds == NULL)
printf(" the list is empty\n"); //空表查询时候提示信息
while(hds != NULL)
{
if(hds->num == innum) //从head开始寻找目标num
{
printf(" the search result: the num is %d, the age is %d \n", hds->num, hds->age);
break;
}
hds = hds->next;
}
printf("\n");
}
/*
*申请结点
*/
LIST * applynode(void)
{
LIST *newnode = (LIST *)malloc(sizeof(LIST));
printf(" please input the newnode's infor: ");
scanf("%d %d", &newnode->num, &newnode->age);
return newnode;
}
/*
*增加结点
*/
//pf为当前的指针,pb为下一个node的指针
LIST *addnode(LIST * hds,LIST *pinsert)
{
LIST *pf,*pb;
pb = hds;
if(hds == NULL) //判断head是否为空
{
hds = pinsert;
pinsert->next = NULL; //空表直接加
}
else
{
while( (pinsert->num > pb->num) && (pb->next!=NULL) )
{
pf = pb;
pb = pb->next; //根据num号选择位置
}
if(pinsert->num <= pb->num) //while循环不成立2个原因,要么插入的num <=,要么就是到尾结点了
{
if(hds == pb)
{
hds = pinsert;
pinsert->next = pb; //如果插在head的后面
}
else
{
pf->next = pinsert;
pinsert->next = pb; //如果插在中间
}
}
else
{
pb->next = pinsert; //如果插在最后
pinsert->next = NULL;
}
}
return hds; //返回更新后的head
}
/*
*删除接点
*/
LIST * deletenode(LIST * hds)
{
LIST *pf, *pb;
int num;
printf(" please input you want to delete num: ");
scanf("%d",&num);
if(hds == NULL) //如为空表, 输出提示信息
{
printf("\n empty list!\n");
goto end;
}
pb = hds;
//不为空则载入列表
while (pb->num != num && pb->next != NULL) //当不是要删除的结点,而且也不是最后一个结点时,继续循环
{
pf=pb;
pb=pb->next; //pf指向当前结点,pb指向下一结点
}
//pb所指向的就是要删除的
if (pb->num == num)
{
if(pb == hds)
hds = pb->next; //如找到被删结点,且为第一结点,则使head指向第二个结点,
else
pf->next=pb->next; //删除中间结点和最后结点程序一致
free(pb); //释放删除节点所占空间
printf(" The node is deleted\n");
}
else
printf(" The node not been foud!\n");
end:
return hds;
}
/*
*菜单界面
*/
void display(void)
{
printf(" |**************MENU**************|\n");
printf(" 1->|******* creat a list *******|\n");
printf(" 2->|****** display a list ******|\n");
printf(" 3->|***** search a list *****|\n");
printf(" 4->|**** add a node ****|\n");
printf(" 5->|*** delete a node ***|\n");
printf(" 6->|*** how many nodes? ***|\n");
printf(" 7->|**** write to file ****|\n");
printf(" 8->|***** read from file *****|\n");
printf(" 9->|****** sort a list ******|\n");
printf("10->|******* Quit the sys *******|\n");
}
/*
*功能选择
*/
void FucSel(void)
{
int choice;
static LIST *heds = NULL; //初始为空,可以判断是否为空表
static LIST *insertp;
//输入的内容必须为1-10
printf("\n please input your choice 1-10 : ");
while((1 != scanf("%d",&choice)) || (choice<1 || choice>10))
printf(" plese input your choice IN 1、2...10: ");
printf("\n");
switch(choice)
{
case 1:
heds = creat();
break;
case 2:
prtlist(heds);
break;
case 3:
search(heds);
break;
case 4:
insertp = applynode();
heds = addnode(heds,insertp);
break;
case 5:
heds = deletenode(heds);
break;
case 6:
printf(" the nodes' num are %u\n", list_node_count(heds));
break;
case 7:
list_wr_file(heds);
break;
case 8:
list_rd_file();
break;
case 9:
sort_list(heds);
prtlist(heds);
break;
case 10:
emptylist(heds);
Flag = 1;
break;
default:
break;
}
}
/*
*释放链表
*/
void emptylist(LIST *hds)
{
LIST *tmp;
tmp = hds;
while(tmp != NULL)
{
free(tmp);
tmp = tmp->next;
}
printf(" **********BYE BYE!!!*********\n");
}
/*
*链表写入文件
*/
int nodecount = 0;
void list_wr_file(LIST *hds)
{
FILE *fp;
LIST *head;
if((fp = fopen("list.bin", "w+")) == NULL) //打开文件
{
printf(" Error in openning file\n");
exit(1);
}
head = hds;
while(head != NULL) //node写入
{
fwrite(head, sizeof(LIST), 1, fp);
head = head->next;
nodecount++;
}
if(fclose(fp) != 0)
{
printf(" Error in closing file\n");
exit(2);
}
if(hds == NULL) //空链表写入提示
printf(" WARNING : LIST IS EMPTY...\n");
else
printf(" Success in writing list to file...\n");
}
/*
*从文件读入链表
*/
void list_rd_file(void)
{
FILE *fp;
LIST *save = (LIST *)malloc(sizeof(LIST)*nodecount);
LIST *tsave = save;
char index;
if((fp = fopen("list.bin", "r")) == NULL) //打开文件
{
printf(" Error in openning file\n");
exit(1);
}
if(getc(fp) == EOF) //判断读入的文件是否为空
{
printf(" This is a empty file\n");
goto end;
}
rewind(fp); //不为空,则从文件头开始读取
for(index = 0; index < nodecount; index++) //读入内容
{
fread(save, sizeof(LIST), 1, fp);
save++;
}
printf("the info from file: \n");
for(index = 0; index < nodecount; index++) //打印内容
{
printf("From File the NO.%d:the num is %d; the age is %d.\n", index+1, tsave->num, tsave->age);
tsave++;
}
nodecount = 0; //读完后,将结点数置为0, 以便下次读取
//新的nodecount,nodecount为外部的
end:
if(fclose(fp) != 0) //关闭文件
{
printf(" Error in closing file\n");
exit(2);
}
}
/*
*NODE统计
*/
unsigned int list_node_count( LIST *hds)
{
LIST *head = hds;
unsigned int count = 0;
while(head != NULL)
{
++count;
head = head->next;
}
return count;
}
/*
*链表排序
*/
void sort_list(LIST *hds)
{
LIST *pb, *pc;
unsigned int ncount; //node的个数
char in_index, out_index;
ncount = list_node_count(hds); //算出当前排序链表node的个数
pb = hds; //内外循环排序,不改变结构,只改变结构体内数据
pc = hds->next;
if(hds == NULL) //空表不需要排序
{
printf(" This is a EMPTY list,NO SORTING!\n");
goto end;
}
if(hds->next == NULL) //一个node的表不需排序
{
printf(" The List On
hds->num, hds->age);
goto end;
}
//链表不为空,也至少存在2个node
for(out_index = 0; out_index < ncount-1; out_index++)
{
for(in_index = out_index+1; in_index < ncount; in_index++)
{
if(pb->num > pc->num)
{
int tmp_num;
tmp_num = pb->num;
pb->num = pc->num;
pc->num = tmp_num;
}
pc = pc->next;
}
pb = pb->next;
pc = pb->next;
}
end:
;
}