用C语言实现线性表的顺序存储(创建,插入,删除和查找)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用C语言实现线性表的顺序存储(创建,插入,删除和查找)相关的知识,希望对你有一定的参考价值。

//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->math;pfloat<&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=head;p1!=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=head;p;p=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=head;p;p=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=head;p1->next!=pfinished;)//对链表进行从大到小排序(这里用冒泡法)
//p1使之总是指向头结点,pfinished使之总是指向已排序好的最前面的结点
//ptemp作为中介,保存p2的上一个结点

for(p2=p1;p2->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=head;p1;p1=p2)

p2=p1->next;//先保存,否则
free(p1);//free后 p1->next数据丢失

追问

用C语言,不是C++啊!

追答

没多大差啊,就一个cout 一个cin,替换成printf 和scanf就可以了啊

参考技术A 参考技术B 那个啥,这个看看书就是了啊

顺序表插入删除算法用C语言来实现

#include<stdio.h>

#include<stdlib.h>

//-------- 线性表的动态分配顺序存储结构 -----------

int LIST_INIT_SIZE=100;   //顺序表存储空间初始尺寸

int LISTINCREMENT=10;  //顺序表存储空间分配增量

typedef  int  ElemType;          //顺序表元素的数据类型为整数

//存储结构定义:顺序表

typedef struct

       ElemType *elem;  //存储线性表元素的数组

       int length;        //表长度

       int listsize;       //存储容量

       int incrementsize;  //扩展增量

SqList;

//-------- 线性表的基本运算 -----------------------------

//辅助函数:显示顺序表元素

void print_Sq (SqList L)

       for(int i=0; i<L.length; i++)  printf("%5d", L.elem[i]);

       printf("\n");

//运算1:初始化空顺序表L

void InitList_Sq(SqList *L, int initsize, int incresize) // 算法2.4

  L->elem = (ElemType *)malloc(initsize*sizeof(ElemType)); //分配数组空间

  L->length=0;  //表长度初值为0

  L->listsize=initsize; //表空间初始尺寸

  L-> incrementsize = incresize;

//运算2:销毁顺序表L// 算法2.8

void DestroyList_Sq(SqList *L)

  free(L->elem); //释放表的数组存储空间

       L->elem=NULL; //清空指向数组的指针及表示表长度、数组尺寸的指示变量

       L->length=0;

       L->listsize=0;

//运算3:在顺序表L中第i个位置前插入新元素e

void ListInsert_Sq (SqList *L,  int i,  ElemType  e)

if(i < 1 || i > L->length+1)

        return ERROR;//   i值不合法

       //动态扩展空间,每次空间不足,空间长度增加 LISTINCREMENT

    if(L->length == L->listsize)

   

        ElemType * increspace = (ElemType *)realloc(L->elem,(L->listsize + LISTINCREMENT) * sizeof(ElemType));

        if(! increspace)

            exit(OVERFLOW);

        L->elem = increspace;

        L->listsize += LISTINCREMENT;

   

       for(int j=L->length-1;j>i-1;j--)

      

              L->elem[j+1]=L->elem[j];

      

       L->elem[i-1]=e;

       L->length++;

       return OK;

//运算4:在顺序表L中删除第i个元素,用输出变量e返回其值

void ListDelete_Sq (SqList *L,  int i,  ElemType*  e) //算法2.7

       *e=L->elem[i-1];

       printf("删除的第%d的元素为:%d\n",i,*e);

       for(int j=i-1;j<L->length;j++)

      

              L->elem[j]=L->elem[j+1];

      

       L->length--;

//运算5:在顺序表L中找到第i个值与e相等的元素,返回其位序,否则返回0

int LocateElem_Sq (SqList  L,  ElemType  e) //算法2.5

for(int i=0;i<L.length;i++)

      

              if(L.elem[i]==e)

                     return i+1;

      

       return 0;

以上是关于用C语言实现线性表的顺序存储(创建,插入,删除和查找)的主要内容,如果未能解决你的问题,请参考以下文章

用C语言建立一个顺序存储的线性表并实现线性表的插入和删除操作

顺序表插入删除算法用C语言来实现

线性表的插入和删除操作代码(C语言)

数据结构实验:线性表的顺序表示和链式表示及插入、删除、查找运算

《线性表的插入和删除算法实现》以及《栈和队列的插入和删除算法实现》的c语言代码

数据结构 线性表 用c语言