怎样在C语言创建线性表?

Python08

怎样在C语言创建线性表?,第1张

#include"stdio.h"\x0d\x0a#include\x0d\x0a \x0d\x0atypedef char ElemType\x0d\x0a \x0d\x0atypedef struct LNode\x0d\x0a{ElemType data\x0d\x0astruct LNode *next\x0d\x0a}LinkList\x0d\x0a \x0d\x0avoid CreatListF(LinkList *&L,ElemType a[],int n) //头插法建表\x0d\x0a{\x0d\x0a LinkList *sint i\x0d\x0a L=(LinkList *)malloc(sizeof(LinkList))\x0d\x0a L->next=NULL\x0d\x0a for(i=0idata=a[i]\x0d\x0a s->next=L->next\x0d\x0a L->next=s\x0d\x0a }\x0d\x0a}\x0d\x0a \x0d\x0avoid CreateListR(LinkList *&L,ElemType a[],int n) //尾插法建表\x0d\x0a{\x0d\x0a LinkList *s,*rint i\x0d\x0a L=(LinkList *)malloc(sizeof(LinkList))\x0d\x0a r=L\x0d\x0a for(i=0idata=a[i]\x0d\x0a r->next=s\x0d\x0a r=s\x0d\x0a }\x0d\x0a r->next=NULL\x0d\x0a}\x0d\x0a\x0d\x0avoid InitList(LinkList *&L)//初始化线性表\x0d\x0a{\x0d\x0a L=(LinkList *)malloc(sizeof(LinkList))\x0d\x0a L->next=NULL\x0d\x0a}\x0d\x0a \x0d\x0avoid DestroyList(LinkList *&L) //销毁线性表\x0d\x0a{\x0d\x0a LinkList *p=L,*q=p->next\x0d\x0a while(q!=NULL)\x0d\x0a {\x0d\x0a free(p)\x0d\x0a p=q\x0d\x0a q=p->next\x0d\x0a }\x0d\x0a free(p)\x0d\x0a}\x0d\x0a \x0d\x0aint ListEmpty(LinkList *L)//判断线性表是否为空\x0d\x0a{\x0d\x0a return(L->next==NULL)\x0d\x0a}\x0d\x0a \x0d\x0aint ListLength(LinkList *L)//求线性表的长度\x0d\x0a{\x0d\x0a LinkList *p=Lint n=0\x0d\x0a while(p->next!=NULL)\x0d\x0a {\x0d\x0a n++p=p->next\x0d\x0a }\x0d\x0a return(n)\x0d\x0a}\x0d\x0a \x0d\x0avoid DispList(LinkList *L) //输出线性表\x0d\x0a{\x0d\x0a LinkList *p=L->next\x0d\x0a while(p!=NULL)\x0d\x0a {\x0d\x0a printf("%c",p->data)\x0d\x0a p=p->next\x0d\x0a }\x0d\x0a}\x0d\x0a \x0d\x0aint GetElem(LinkList *L,int i,ElemType &e) //求线性表中某个数据元素值\x0d\x0a{\x0d\x0a int j=0\x0d\x0a LinkList *p=L\x0d\x0a while(jnext\x0d\x0a }\x0d\x0a if(p==NULL)\x0d\x0a return 0\x0d\x0a else\x0d\x0a {\x0d\x0a e=p->datareturn 1\x0d\x0a }\x0d\x0a}\x0d\x0a \x0d\x0aint LocateElem(LinkList *L,ElemType e)//按元素值查找\x0d\x0a{\x0d\x0a LinkList *p=L->next\x0d\x0a int i=1\x0d\x0a while(p!=NULL&&p->data!=e)\x0d\x0a {\x0d\x0a p=p->nexti++\x0d\x0a }\x0d\x0a if(p==NULL)return(0)\x0d\x0a else return(i)\x0d\x0a}\x0d\x0a \x0d\x0aint ListInsert(LinkList *&L,int i,ElemType e) //插入数据元素\x0d\x0a{\x0d\x0a int j=0\x0d\x0a LinkList *p=L,*s\x0d\x0a while(jnext\x0d\x0a }\x0d\x0a if(p==NULL)return 0\x0d\x0a else\x0d\x0a {\x0d\x0a s=(LinkList *)malloc(sizeof(LinkList))\x0d\x0a s->data=es->next=p->nextp->next=s\x0d\x0a return 1\x0d\x0a }\x0d\x0a}\x0d\x0a \x0d\x0aint ListDelete(LinkList *&L,int i,ElemType &e) //删除数据元素\x0d\x0a{\x0d\x0a int j=0\x0d\x0a LinkList *p=L,*q\x0d\x0a while(jnext\x0d\x0a }\x0d\x0a if(p==NULL)\x0d\x0a return 0\x0d\x0a else\x0d\x0a {\x0d\x0a q=p->next\x0d\x0a if(q==NULL)return 0\x0d\x0a e=q->data\x0d\x0a p->next=q->next\x0d\x0a free(q)\x0d\x0a return 1\x0d\x0a }\x0d\x0a}\x0d\x0a\x0d\x0aint main()\x0d\x0a{\x0d\x0a ElemType e,a[5]={'a','b','c','d','e'}\x0d\x0a LinkList *h\x0d\x0a \x0d\x0a InitList(h) //初始化顺序表h\x0d\x0a CreateListR(h,&a[0],5)//依次采用尾插入法插入a,b,c,d,e元素\x0d\x0a printf("单链表为:")\x0d\x0a DispList(h) printf("\n")//输出顺序表h\x0d\x0a \x0d\x0a printf("该单链表的长度为:")\x0d\x0a printf("%d",ListLength(h))printf("\n") //输出顺序表h的长度\x0d\x0a if(ListEmpty(h)) printf("该单链表为空。\n") \x0d\x0a else printf("该单链表不为空。\n") //判断顺序表h是否为空\x0d\x0a \x0d\x0a GetElem(h,3,e)printf("该单链表的第3个元素为:")\x0d\x0a printf("%c",e)printf("\n") //输出顺序表h的第3个元素\x0d\x0a printf("该单链表中a的位置为:")\x0d\x0a printf("%d",LocateElem(h,'a'))printf("\n") //输出元素'a'的位置\x0d\x0a \x0d\x0a ListInsert(h,4,'f') //在第4个元素位置插入'f'素\x0d\x0a printf("在第4 个元素位置上插入'f'后单链表为:")\x0d\x0a DispList(h)printf("\n") //输出顺序表h\x0d\x0a \x0d\x0a ListDelete(h,3,e) //删除L的第3个元素\x0d\x0a printf("删除第3个元素后单链表为:")\x0d\x0a DispList(h)printf("\n") //输出顺序表h\x0d\x0a \x0d\x0a DestroyList(h)//释放顺序表h\x0d\x0a return 0\x0d\x0a}

//C++课程设计---学生成绩管理系统

#include <stdio.h>

#include <string.h>

#include <iostream.h>

#include <stdlib.h>

#include <windows.h>

typedef struct studentinfo //结构体定义

{

int num//学号

char name[64]//姓名

int sex//性别,1为男性,0为女性

float math//数学

float english//英语

float politic//政治

float chinese//语文

float total//总成绩

struct studentinfo *next

}STUDENT

#define FILENAME "D:\\1.txt"

//定义默认的数据库文件

#define DELAYTIME 1500

//显示信息,延时

void create_menu()

STUDENT * new_student()

STUDENT* create_linkbyfile(char *)

STUDENT *del_info(STUDENT *)

int save_info(char *,STUDENT *,int)

int find_infile_printf(char *)

int pri_whole_link(STUDENT *)

STUDENT* printf_sort(STUDENT *)

void free_link(STUDENT *)

void main() //主函数

{

create_menu()

}

STUDENT * reverse(STUDENT *head)

//功能:链表反转顺序

//参数:head链表头结点指针

{

STUDENT *ptemp,*p1

if(head==NULL)

{

return 0

}

p1=head//p1使之永远指向排好序的第一个结点,初值为head,head使之永远是已经排好序的最后一个结点

while(head->next!=NULL)//本次循环使ptemp排好序

{

ptemp=head->next//ptemp指向未排好序的第一个结点

head->next=ptemp->next//

ptemp->next=p1//ptemp也排好序了,ptemp变成排好序的第一个结点了

p1=ptemp//再次让p1成为第一个排好序的结点

}

return p1//头结点为第一个结点

}

void create_menu()

//功能:输出功能菜单,提供人-机接口

{

char menu_Num

STUDENT *head=NULL

char ch

char file_name[256]

while(1)

{

system("cls")

cout<<"\t\t学生成绩管理系统\n"

cout<<"##########################################\n"

cout<<"#\t\t 1.新增学生信息\t\t #\n"

cout<<"#\t\t 2.加载数据库\t\t #\n"

cout<<"#\t\t 3.删除学生信息\t\t #\n"

cout<<"#\t\t 4.保存学生信息\t\t #\n"

cout<<"#\t\t 5.数据库查询\t\t #\n"

cout<<"#\t\t 6.原序输出\t\t #\n"

cout<<"#\t\t 7.排序输出\t\t #\n"

cout<<"#\t\t 8.退出\t\t\t #\n"

cout<<"##########################################\n"

cout<<"请输入操作编号:"

cin>>menu_Num

switch (menu_Num)

{

case '1':

free_link(head)//释放链表空间

head=new_student()//新增学生信息

break

case '2':

free_link(head)//释放链表空间

cout<<"请输入要加载的数据库文件的路径"<<endl

cin>>file_name

head=create_linkbyfile(file_name)//读取数据文件

if(head!=NULL)

{

cout<<"数据库"<<file_name<<"已加载"<<endl

Sleep(DELAYTIME)

}

break

case '3':

del_info(head)//删除学生信息

break

case '4'://保存学生信息

if (head==NULL)

{

cout<<"请先生成学生信息"<<endl

Sleep(DELAYTIME)

}

else

{

cout<<"想将学生信息保存到哪个数据库文件?"

cin>>file_name

cout<<"请选择保存方式:0追加到文件末尾 1覆盖文件\n"

cin>>menu_Num

if(save_info(file_name,head,menu_Num-'0')==0)//0表示追加,1表示覆盖

{

cout<<"信息保存失败\n"

}

else

{

cout<<"数据已保存到"<<file_name<<endl

Sleep(DELAYTIME)

}

}

break

case '5':

find_infile_printf(FILENAME)//数据库查询

break

case '6'://原序输出信息

pri_whole_link(head)

cout<<"返回主菜单? Y/N\t"

do

{

cin>>ch

}while(ch!='Y'&&ch!='y')

break

case '7'://排序输出信息

do

{

if((head=printf_sort(head))==NULL)

{

cout<<"数据库未加载"<<endl

Sleep(DELAYTIME)

break

}

else

{

cout<<"选择其他方式排序? Y/N\t"

cin>>ch

}

}while(ch=='Y'||ch=='y')

break

case '8':

free_link(head)//释放链表空间

exit(0)

break

default:

cout<<"输入有误!请重新输入!"<<endl

Sleep(DELAYTIME)

break

}

}

}

STUDENT * new_student()

//功能:创建学生信息(通过链表)

//返回值:头结点指针

{

STUDENT *pnew,*p,*head

float *pfloat

char ch

head=NULL

do

{

system("cls")

pnew=(STUDENT *)malloc(sizeof(STUDENT)*1)

cout<<"请输入学生的学号(0表示取消): "

cin>>pnew->num

if(0>=pnew->num)

{

break

}

cout<<"请输入学生的姓名:"

cin>>pnew->name

while(1)

{

cout<<"请输入学生的性别:0/1\t"

cin>>pnew->sex

if(pnew->sex&&pnew->sex-1)

{

cout<<"性别输入错误,0表示女性,1表示男性,请重新输入"<<endl

}

else

{

break

}

}

cout<<"请依次输入学生的数学、英语、政治、语文成绩:"<<endl

for(pnew->total=0,pfloat=&pnew->mathpfloat<&pnew->math+4)

{

cin>>*pfloat

if(*pfloat<0||*pfloat>150)

{

cout<<"成绩输入错误,只能为0~150"<<endl

}

else

{

pnew->total+=*pfloat

pfloat++

}

}

if(head==NULL)

{

head=pnew

}

else

{

p->next=pnew

}

p=pnew

pnew->next=NULL

cout<<"##########################该学生信息已生成#########################\n"

cout<<"建立另一个学生的信息? Y/N\t"

cin>>ch

}while(ch=='Y'||ch=='y')

return head

}

STUDENT* create_linkbyfile(char *filename)

//功能:读取文件,创建链表

//参数:如果filename不为空,则打开该文件,如果filename为空,要求输入文件位置

//创建的链表的所有结点的next全部修改,指向物理地址上的下一个结点

{

system("cls")

FILE *fp

STUDENT *head,*ptemp,*pnew

head=NULL//初始化head为空

if(filename==NULL)//若filename为空,要求输入文件绝对地址

{

char file_name[256]

cout<<"请输入数据库文件的路径:"<<endl

cin>>file_name

if(NULL==(fp=fopen(file_name,"rb")))

{

cout<<"数据库连接失败\n"

return 0

}

}

else

{

if(NULL==(fp=fopen(filename,"rb")))

{

cout<<"数据库连接失败\n"

return 0

}

}

for(ptemp=NULL)

{

pnew=(STUDENT *)malloc(sizeof(STUDENT)*1)

if(fread(pnew,sizeof(STUDENT),1,fp)!=NULL)

{

if(ptemp!=NULL)

{

ptemp->next=pnew

}

else

{

head=pnew

}

ptemp=pnew

}

else

{

if(ptemp!=NULL)

{

ptemp->next=NULL

}

else

{

head=NULL

}

free(pnew)

break

}

}

fclose(fp)

return head

}

STUDENT *del_info(STUDENT *head)

//根据学号,删除链表的结点

{

system("cls")

STUDENT *p1,*p2

int num

if (head==NULL)

{

cout<<"数据库未加载"<<endl

Sleep(DELAYTIME)

return 0

}

cout<<"请输入要删除学生的学号:"

cin>>num

for(p1=headp1!=NULL)

{

if(p1->num==num)//找到

{

if(p1==head)//要删除的结点是头结点

{

head=p1->next

}

else

{

p2->next=p1->next

}

cout<<"成功删除!!"

}

p2=p1

p1=p1->next

}

return head

}

int save_info(char *filename,STUDENT *head,int flag)

//功能:将链表按Binary写入文件末尾

//参数:

//1.filename文件名,绝对地址

//2.head指向链表的头结点

//3.flag 0追加或1覆盖数据

//返回值:失败则返回0

{

system("cls")

FILE *fp

STUDENT *p

char openmethod[8]

if(flag==0)

{

strcpy(openmethod,"ab+")//追加

}

else

{

strcpy(openmethod,"w")//覆盖

}

if(NULL==(fp=fopen(filename,openmethod)))//

{

cout<<"数据库连接失败"<<endl

Sleep(DELAYTIME)

return 0

}

else

{

for(p=headpp=p->next)

{

if((fwrite(p,sizeof(STUDENT),1,fp))==NULL)

{

cout<<"数据库创建失败"<<endl

return 0

}

}

}

fclose(fp)

return 1

}

int find_infile_printf(char *filename)

//功能:根据学号和姓名来查询某个学生

//参数:filename数据库文件

//返回值:失败返回0

//直接搜索文件,缺点是速度慢

//也可先根据文件创建链表,再搜索链表,缺点是如果文件较大,占用内存多

{

system("cls")

FILE *fp

STUDENT stu

int num

char stu_name[64]

char ch

if(filename==NULL)

{

return 0

}

do

{

memset(stu_name,0,sizeof(stu_name))

cout<<"查询学号或查询姓名? 1查询学号 0查询姓名"

//flag=1根据学号来查询,flag=0根据姓名来查询

cin>>num

if(num==1)

{

cout<<"输入要查询的学号:"

cin>>num

cout<<"正在为您查询学号为"<<num<<"的学生……"<<endl

}

else if(num==0)

{

cout<<"输入要查询的姓名:"

cin>>stu_name

cout<<"正在为您查询姓名为"<<stu_name<<"的学生……"<<endl

}

else

{

cout<<"输入有误"<<endl

return 0

}

if(NULL==(fp=fopen(filename,"rw")))

{

cout<<"数据库连接失败\n"

return 0

}

else

{

while(fread(&stu,sizeof(STUDENT),1,fp)!=NULL)

{

if(strcmp(stu.name,stu_name)==0||stu.num==num)

{

cout<<"学号\t姓名\t性别\t数学\t英语\t政治\t语文\t总成绩\n"

//输出该学生的所有信息

cout<<stu.num<<"\t"<<stu.name<<"\t"<<stu.sex<<"\t"<<stu.math<<"\t"<<stu.english<<"\t"<<stu.politic<<"\t"<<stu.chinese<<"\t"<<stu.total<<endl

//不加break可支持多个相同数据的索引

}

}

}

cout<<"##########################查询完毕#########################\n"

cout<<"查询另一个学生的信息? Y/N\t"

cin>>ch

}while(ch=='Y'||ch=='y')

fclose(fp)

return 1

}

int pri_whole_link(STUDENT *head)

//功能:显示整条链表的学生信息

//参数:head 头结点指针,如果head为空,返回空

{

system("cls")

STUDENT* p

if (head==NULL)

{

cout<<"数据库未加载"<<endl

Sleep(DELAYTIME)

return 0

}

cout<<"学号\t姓名\t性别\t数学\t英语\t政治\t语文\t总成绩\n"

for(p=headpp=p->next)

{

cout<<p->num<<"\t"<<p->name<<"\t"<<p->sex<<"\t"<<p->math<<"\t"<<p->english<<"\t"<<p->politic<<"\t"<<p->chinese<<"\t"<<p->total<<endl

}

return 1

}

STUDENT* printf_sort(STUDENT *head)

//功能:根据学号|某科目成绩|总成绩对链表进行排序,然后输出

//参数:head链表头指针,如果head为空,返回空

//返回值:返回新的链表的头结点指针

{

system("cls")

STUDENT *p1,*p2,*ptemp,*pfinished=NULL

char num

char flag

if (head==NULL)

{

return 0

}

cout<<"选择排序依据 0.数学成绩1.英语成绩2.政治成绩3.语文成绩4.总成绩\n"

while(1)

{

cin>>num

if(num>'4'||num<'0')

{

cout<<"输入有误,请重新输入 0~4"<<endl

}

else

{

break

}

}

cout<<"升序/降序输出? 0.降序1.升序"

while(1)

{

cin>>flag

if(flag>'1'||flag<'0')

{

cout<<"输入有误,请重新输入 0~1"<<endl

}

else

{

break

}

}

for(p1=headp1->next!=pfinished)//对链表进行从大到小排序(这里用冒泡法)

//p1使之总是指向头结点,pfinished使之总是指向已排序好的最前面的结点

//ptemp作为中介,保存p2的上一个结点

{

for(p2=p1p2->next!=pfinished)

{

if(*(&(p2->math)+num-'0')<*(&(p2->next->math)+num-'0'))//p2的值小于p2->next的值,交换 ptemp p2 p2->next

{

if(p2==p1)//头结点要交换

{

p1=p2->next

p2->next=p1->next

p1->next=p2

ptemp=p1

}

else

{

ptemp->next=p2->next

ptemp=p2->next

p2->next=ptemp->next

ptemp->next=p2

}

}

else//不需要交换,则p2、ptemp前进1位

{

ptemp=p2

p2=p2->next

}

}

pfinished=p2

}

if(flag=='1')

{

p1=reverse(p1)

}

pri_whole_link(p1)

cout<<"##########################信息显示完毕#########################\n"

return p1

}

void free_link(STUDENT *head)

//释放链表空间,如果head,什么都不做

{

STUDENT *p1,*p2

for(p1=headp1p1=p2)

{

p2=p1->next//先保存,否则

free(p1)//free后 p1->next数据丢失

}

}