?? algo2-6.cpp
字號(hào):
// algo2-6.cpp 利用單鏈表結(jié)構(gòu)處理教科書圖2.1(學(xué)生健康登記表)
#include"c1.h"
#define NAMELEN 8 // 姓名最大長(zhǎng)度
#define CLASSLEN 4 // 班級(jí)名最大長(zhǎng)度
struct stud // 記錄的結(jié)構(gòu)
{
char name[NAMELEN+1];
long num;
char sex;
int age;
char Class[CLASSLEN+1];
int health;
};
typedef stud ElemType; // 鏈表結(jié)點(diǎn)元素類型為結(jié)構(gòu)體
#include"c2-2.h"
char sta[3][9]={"健康 ","一般 ","神經(jīng)衰弱"}; // 健康狀況(3類)
FILE *fp;
Status InitList(LinkList &L)
{ // 操作結(jié)果:構(gòu)造一個(gè)空的線性表L
L=(LinkList)malloc(sizeof(LNode)); // 產(chǎn)生頭結(jié)點(diǎn),并使L指向此頭結(jié)點(diǎn)
if(!L) // 存儲(chǔ)分配失敗
exit(OVERFLOW);
L->next=NULL; // 指針域?yàn)榭? return OK;
}
Status ListTraverse(LinkList L,void(*vi)(ElemType)) // 拷自bo2-2.cpp
{ // 初始條件:線性表L已存在
// 操作結(jié)果:依次對(duì)L的每個(gè)數(shù)據(jù)元素調(diào)用函數(shù)vi()。一旦vi()失敗,則操作失敗
LinkList p=L->next;
while(p)
{
vi(p->data);
p=p->next;
}
printf("\n");
return OK;
}
void InsertAscend(LinkList L,ElemType e) // 此函數(shù)是由bo2-9.cpp中的同名函數(shù)改寫
{ // 按學(xué)號(hào)非降序插入
LinkList q=L,p=L->next;
while(p&&e.num>p->data.num)
{
q=p;
p=p->next;
}
q->next=(LinkList)malloc(sizeof(LNode)); // 插在q后
q->next->data=e;
q->next->next=p;
}
void Print(stud e)
{ // 顯示記錄e的內(nèi)容
printf("%-8s %6ld",e.name,e.num);
if(e.sex=='m')
printf(" 男");
else
printf(" 女");
printf("%5d %-4s",e.age,e.Class);
printf("%9s\n",sta[e.health]);
}
void ReadIn(stud &e)
{ // 由鍵盤輸入結(jié)點(diǎn)信息
printf("請(qǐng)輸入姓名(<=%d個(gè)字符): ",NAMELEN);
scanf("%s",e.name);
printf("請(qǐng)輸入學(xué)號(hào): ");
scanf("%ld",&e.num);
printf("請(qǐng)輸入性別(m:男 f:女): ");
scanf("%*c%c",&e.sex);
printf("請(qǐng)輸入年齡: ");
scanf("%d",&e.age);
printf("請(qǐng)輸入班級(jí)(<=%d個(gè)字符): ",CLASSLEN);
scanf("%s",e.Class);
printf("請(qǐng)輸入健康狀況(0:%s 1:%s 2:%s):",sta[0],sta[1],sta[2]);
scanf("%d",&e.health);
}
void WriteToFile(stud e)
{ // 將結(jié)點(diǎn)信息寫入fp指定的文件
fwrite(&e,sizeof(stud),1,fp);
}
Status ReadFromFile(stud &e)
{ // 由fp指定的文件讀取結(jié)點(diǎn)信息到e
int i;
i=fread(&e,sizeof(stud),1,fp);
if(i==1) // 讀取文件成功
return OK;
else
return ERROR;
}
Status FindFromNum(LinkList L,long num,LinkList &p,LinkList &q)
{ // 查找表中學(xué)號(hào)為num的結(jié)點(diǎn),如找到,q指向此結(jié)點(diǎn),p指向q的前驅(qū),
// 并返回TRUE;如無此元素,則返回FALSE
p=L;
while(p)
{
q=p->next;
if(q&&q->data.num>num) // 因?yàn)槭前磳W(xué)號(hào)非降序排列
break;
if(q&&q->data.num==num) // 找到該學(xué)號(hào)
return TRUE;
p=q;
}
return FALSE;
}
Status FindFromName(LinkList L,char name[],LinkList &p,LinkList &q)
{ // 查找表中姓名為name的結(jié)點(diǎn),如找到,q指向此結(jié)點(diǎn),p指向q的前驅(qū),
// 并返回TRUE;如無此元素,則返回FALSE
p=L;
while(p)
{
q=p->next;
if(q&&!strcmp(q->data.name,name)) // 找到該姓名
return TRUE;
p=q;
}
return FALSE;
}
Status DeleteElem(LinkList L,long num)
{ // 刪除表中學(xué)號(hào)為num的元素,并返回TRUE;如無此元素,則返回FALSE
LinkList p,q;
if(FindFromNum(L,num,p,q)) // 找到此結(jié)點(diǎn),且q指向其,p指向其前驅(qū)
{
p->next=q->next;
free(q);
return TRUE;
}
return FALSE;
}
Status DeleteElem(LinkList L,char name[])
{ // 刪除表中姓名為name的元素,并返回TRUE;如無此元素,則返回FALSE
LinkList p,q;
if(FindFromName(L,name,p,q)) // 找到此結(jié)點(diǎn),且q指向其,p指向其前驅(qū)
{
p->next=q->next;
free(q);
return TRUE;
}
return FALSE;
}
void Modify(ElemType &e)
{ // 修改結(jié)點(diǎn)內(nèi)容
char s[80];
Print(e); // 顯示原內(nèi)容
printf("請(qǐng)輸入待修改項(xiàng)的內(nèi)容,不修改的項(xiàng)按回車鍵保持原值:\n");
printf("請(qǐng)輸入姓名(<=%d個(gè)字符): ",NAMELEN);
gets(s);
if(strlen(s))
strcpy(e.name,s);
printf("請(qǐng)輸入學(xué)號(hào): ");
gets(s);
if(strlen(s))
e.num=atol(s);
printf("請(qǐng)輸入性別(m:男 f:女): ");
gets(s);
if(strlen(s))
e.sex=s[0];
printf("請(qǐng)輸入年齡: ");
gets(s);
if(strlen(s))
e.age=atoi(s);
printf("請(qǐng)輸入班級(jí)(<=%d個(gè)字符): ",CLASSLEN);
gets(s);
if(strlen(s))
strcpy(e.Class,s);
printf("請(qǐng)輸入健康狀況(0:%s 1:%s 2:%s):",sta[0],sta[1],sta[2]);
gets(s);
if(strlen(s))
e.health=atoi(s); // 修改完畢
}
#define N 4 // student記錄的個(gè)數(shù)
void main()
{
stud student[N]={{"王小林",790631,'m',18,"計(jì)91",0},
{"陳紅",790632,'f',20,"計(jì)91",1},
{"劉建平",790633,'m',21,"計(jì)91",0},
{"張立立",790634,'m',17,"計(jì)91",2}}; // 表的初始記錄
int i,j,flag=1;
long num;
char filename[13],name[NAMELEN+1];
ElemType e;
LinkList T,p,q;
InitList(T); // 初始化鏈表
while(flag)
{
printf("1:將結(jié)構(gòu)體數(shù)組student中的記錄按學(xué)號(hào)非降序插入鏈表\n");
printf("2:將文件中的記錄按學(xué)號(hào)非降序插入鏈表\n");
printf("3:鍵盤輸入新記錄,并將其按學(xué)號(hào)非降序插入鏈表\n");
printf("4:刪除鏈表中第一個(gè)有給定學(xué)號(hào)的記錄\n");
printf("5:刪除鏈表中第一個(gè)有給定姓名的記錄\n");
printf("6:修改鏈表中第一個(gè)有給定學(xué)號(hào)的記錄\n");
printf("7:修改鏈表中第一個(gè)有給定姓名的記錄\n");
printf("8:查找鏈表中第一個(gè)有給定學(xué)號(hào)的記錄\n");
printf("9:查找鏈表中第一個(gè)有給定姓名的記錄\n");
printf("10:顯示所有記錄 11:將鏈表中的所有記錄存入文件 12:結(jié)束\n");
printf("請(qǐng)選擇操作命令: ");
scanf("%d",&i);
switch(i)
{
case 1: for(j=0;j<N;j++)
InsertAscend(T,student[j]);
break;
case 2: printf("請(qǐng)輸入文件名: ");
scanf("%s",filename);
if((fp=fopen(filename,"rb"))==NULL)
printf("打開文件失敗!\n");
else
{
while(ReadFromFile(e))
InsertAscend(T,e);
fclose(fp);
}
break;
case 3: ReadIn(e);
InsertAscend(T,e);
break;
case 4: printf("請(qǐng)輸入待刪除記錄的學(xué)號(hào): ");
scanf("%ld",&num);
if(!DeleteElem(T,num))
printf("沒有學(xué)號(hào)為%ld的記錄\n",num);
break;
case 5: printf("請(qǐng)輸入待刪除記錄的姓名: ");
scanf("%s",name);
if(!DeleteElem(T,name))
printf("沒有姓名為%s的記錄\n",name);
break;
case 6: printf("請(qǐng)輸入待修改記錄的學(xué)號(hào): ");
scanf("%ld%*c",&num); // %*c吃掉回車符
if(!FindFromNum(T,num,p,q))
printf("沒有學(xué)號(hào)為%ld的記錄\n",num);
else
{
Modify(q->data);
if(q->data.num!=num) // 學(xué)號(hào)被修改
{
p->next=q->next; // 把q所指的結(jié)點(diǎn)從L中刪除
InsertAscend(T,q->data); // 把元素插入L
free(q); // 刪除q
}
}
break;
case 7: printf("請(qǐng)輸入待修改記錄的姓名: ");
scanf("%s%*c",name); // %*c吃掉回車符
if(!FindFromName(T,name,p,q))
printf("沒有姓名為%s的記錄\n",name);
else
{
num=q->data.num; // 學(xué)號(hào)存入num
Modify(q->data);
if(q->data.num!=num) // 學(xué)號(hào)被修改
{
p->next=q->next; // 把q所指的結(jié)點(diǎn)從L中刪除
InsertAscend(T,q->data); // 把元素插入L
free(q); // 刪除q
}
}
break;
case 8: printf("請(qǐng)輸入待查找記錄的學(xué)號(hào): ");
scanf("%ld",&num);
if(!FindFromNum(T,num,p,q))
printf("沒有學(xué)號(hào)為%ld的記錄\n",num);
else
Print(q->data);
break;
case 9: printf("請(qǐng)輸入待查找記錄的姓名: ");
scanf("%s",name);
if(!FindFromName(T,name,p,q))
printf("沒有姓名為%s的記錄\n",name);
else
Print(q->data);
break;
case 10:printf(" 姓名 學(xué)號(hào) 性別 年齡 班級(jí) 健康狀況\n");
ListTraverse(T,Print);
break;
case 11:printf("請(qǐng)輸入文件名: ");
scanf("%s",filename);
if((fp=fopen(filename,"wb"))==NULL)
printf("打開文件失敗!\n");
else
ListTraverse(T,WriteToFile);
fclose(fp);
break;
case 12:flag=0;
}
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -