您的位置:首页 > 理论基础 > 数据结构算法

线性表的基本操作实现 - 链表与顺序表

2017-05-14 19:38 429 查看
注:实验用书为 数据结构 C语言版 第2版,人民邮电出版社出版。

实验题目:学生管理系统的设计与实现

实验环境:Visual C++ 6.0或其他C++环境

一、实验目的

1、掌握线性表的定义;

2、掌握线性表的基本操作,如建立、查找、插入和删除等。

二、实验内容

定义一个包含学生信息(学号,姓名,成绩)的顺序表和链表,使其具有如下功能:

1、根据指定学生个数,逐个输入学生信息;

2、逐个显示学生表中所有学生的相关信息;

3、根据姓名进行查找,返回此学生的学号和成绩;

4、根据指定的位置可返回相应的信息(学号,姓名,成绩);

5、给定一个学生信息,插入到表中指定的位置;

6、删除指定位置的学生记录;

7、统计表中学生个数。

三、实验提示

1、学生信息的定义

typedef struct {

char no[8]; //8位学号

char name[20]; //姓名

int price; //成绩

}Student;

2、顺序表的定义

typedef struct {

Student *elem; //指向数据元素的基地址

int length; //线性表的当前长度

}SqList;

3、链表的定义

typedef struct LNode{

Student data; //数据域

struct LNode *next; //指针域

}LNode,*LinkList;

四、代码

顺序表方法:

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <cstdlib>
using namespace std;
#define MAXSIZE 100//假设的表的最大长度;
typedef struct{
char no[8];   //8位学号
char name[20]; //姓名
int price;     //成绩
}Student,ElemType;
typedef  struct {
Student   *elem=NULL;     //指向数据元素的基地址
int  length;       //线性表的当前长度
}SqList;

SqList L;//声明一个数据表

void InitList()
{//构造一个空的顺序表
L.elem=new ElemType[MAXSIZE];
if(!L.elem) exit(0);//存储分配失败退出
L.length=0;
}
int menu_select()//选择菜单函数
{
char s[3];
int c;
printf("\n         ***************主菜单**************\n");
printf("         *    1. 录入新记录                *\n");
printf("         *    2. 浏览显示所有记录          *\n");
printf("         *    3. 按姓名查询记录并显示      *\n");
printf("         *    4. 按编号查询记录并显示      *\n");
printf("         *    5. 插入记录                  *\n");
printf("         *    6. 删除记录                  *\n");
printf("         *    7. 统计记录                  *\n");
printf("         *    8. 退出                      *\n");
printf("         ***********************************\n\n");

do
{
printf("         请选择操作(1-8):");
scanf("%s",s);
c=atoi(s);
}while(c<0||c>8); /*选择项不在~8之间重输*/
return(c); /*返回选择项,主程序根据该数调用相应的函数*/
}
/*数据表取值*/
void Create()
{//新建学生数据
int n;
cout<<"根据指定学生个数,逐个输入学生信息:"<<endl;
cout<<"学生个数n=";
cin>>n;
if(n<1||L.length+n>MAXSIZE){
cout<<"创建失败"<<endl;
return ;
}
for(int i=0;i<n;i++)//逐个添加数据
{
cout<<"第"<<i+1<<"个学生数据"<<endl<<"姓名:";
cin>>L.elem[L.length].name;
cout<<"学号:";
cin>>L.elem[L.length].no;
cout<<"成绩:";
cin>>L.elem[L.length].price;
L.length++;//每创建成功一个,则更新一次数量
}
cout<<"***操作成功***"<<endl;
}
void ShowAllDate()
{
if(L.length<1)
{
cout<<endl<<"    很遗憾,空表中没有任何记录可供显示!"<<endl;
return ;
}
cout<<"************ STUDENT ************"<<endl;
cout<<"  编号     姓名     学号     成绩"<<endl;
cout<<"---------------------------------"<<endl;
for(int i=0;i<L.length;i++)
{
cout<<"   "<<i+1<<"      "<<L.elem[i].name<<"      "<<L.elem[i].no<<"      "<<L.elem[i].price<<endl;
}
cout<<"*********************************"<<endl;
cout<<"***操作成功***"<<endl;
}
void SearchByName()
{
if(L.length<1){
cout<<"查询失败"<<endl;
return ;
}
char s[20];
cout<<"根据姓名进行查找,返回此学生的学号和成绩"<<endl;
cout<<"请输入学生姓名:";
cin>>s;
int flag=0;
for(int i=0;i<L.length;i++)
{
if(strstr(L.elem[i].name,s))
{
if(flag==0)
{
cout<<"************ STUDENT ************"<<endl;
cout<<"  编号     姓名     学号     成绩"<<endl;
cout<<"---------------------------------"<<endl;
flag=1;
}
cout<<"   "<<i+1<<"      "<<L.elem[i].name<<"      "<<L.elem[i].no<<"      "<<L.elem[i].price<<endl;
}
}
if(flag==1)
{
cout<<"*********************************"<<endl;
}
cout<<"***操作成功***"<<endl;
}
void SearchByID()
{
if(L.length<1){
cout<<"查询失败"<<endl;
return ;
}
int i;
cout<<"根据指定的位置可返回相应的信息(学号,姓名,成绩)"<<endl;
cout<<"请输入学生编号:";
cin>>i;
if(i<1||i>L.length)
{
cout<<"编号错误"<<endl;
return ;
}
cout<<"************ STUDENT ************"<<endl;
cout<<"  编号     姓名     学号     成绩"<<endl;
cout<<"---------------------------------"<<endl;
i--;
cout<<"   "<<i+1<<"      "<<L.elem[i].name<<"      "<<L.elem[i].no<<"      "<<L.elem[i].price<<endl;
cout<<"*********************************"<<endl;
cout<<"***操作成功***"<<endl;
}
void GetElem(SqList L,int i,ElemType &e)
{
if(i<1 ||i>L.length){////i值不合法
cout<<"索引["<<i<<"]的数据不存在"<<endl;
}
e=L.elem[i-1];
cout<<"***操作成功***"<<endl;
}
/*int LocateElem(SqList L,ElemType e)
{//在顺序表L中查找值为e的数据元素,返回其序号
for(int i=0;i<L.length;i++)
{
if(L.elem[i]==e)
return i+1;
return 0;
}
}*/
/*插入数据*/
bool InsertByID()
{//在顺序表L中第i个位置插入新的元素e,i值的合法范围三1<=i<=L.length+1
int i;
ElemType e;
cout<<"给定一个学生信息,插入到表中指定的位置"<<endl;
ShowAllDate();
cout<<"请输入插入的位置:";
cin>>i;
if((i<1)||(i>L.length+1)){cout<<"位置不合法"; return false;}//i值不合法
if(L.length==MAXSIZE) {cout<<"存储空间已满";return false;}//存储空间已满
cout<<"请输入插入的数据:"<<endl;
cout<<"姓名:";
cin>>e.name;
cout<<"学号:";
cin>>e.no;
cout<<"成绩:";
cin>>e.price;
for(int j=L.length-1;j>=i-1;j--){
L.elem[j+1]=L.elem[j];
}
L.elem[i-1]=e;
++L.length;
cout<<"***操作成功***"<<endl;
return true;
}
bool DeleteByID()
{//在顺序表L中删除第i个元素,i值的合法范围三1<=i<=L.length
int i;
cout<<"删除指定位置的学生记录"<<endl;
cout<<"位置i=";
cin>>i;
if((i<1)||(i>L.length)){
cout<<"位置不合法";
return false;
}
for(int j=i;j<=L.length-1;j++){
L.elem[j-1]=L.elem[j];
}
--L.length;
cout<<"***操作成功***"<<endl;
return true;
}
int main()
{
system("color 3e");             /*清屏*/
InitList();
for(;;)               /*无限循环*/
{
switch(menu_select())               /*调用主菜单函数,返回值整数作开关语句的条件*/
{
case 1: Create();break;        //新建记录
case 2: ShowAllDate();break;          //显示全部记录
case 3: SearchByName();break;         //按姓名查找记录
case 4: SearchByID();break;         //按编号查找数据
case 5: InsertByID();break;        //插入记录
case 6: DeleteByID();break;    //通过ID删除记录
case 7: cout<<"当前存档学生个数为:"<<L.length;break;   //显示表中学生个数
case 8: exit(0);                    //程序结束*/
}

}
return 0;
}


链表方法:

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <cstdlib>
using namespace std;
#define MAXSIZE 100//假设的表的最大长度;
typedef struct{
char no[8];   //8位学号
char name[20]; //姓名
int price;     //成绩
}Student,ElemType;
typedef struct LNode{
Student data;       //数据域
struct LNode  *next=NULL;   //指针域
}LNode,*LinkList;
void InitList(LinkList &L)
{//构造一个空的顺序表
L=new LNode;
L->next=NULL;
}
int menu_select()//选择菜单函数
{
char s[3];
int c;
printf("\n         ***************主菜单**************\n");
printf("         *    1. 录入新记录                *\n");
printf("         *    2. 浏览显示所有记录          *\n");
printf("         *    3. 按姓名查询记录并显示      *\n");
printf("         *    4. 按编号查询记录并显示      *\n");
printf("         *    5. 插入记录                  *\n");
printf("         *    6. 删除记录                  *\n");
printf("         *    7. 统计记录                  *\n");
printf("         *    8. 退出                      *\n");
printf("         ***********************************\n\n");

do
{
printf("         请选择操作(1-8):");
scanf("%s",s);
c=atoi(s);
}while(c<0||c>8); /*选择项不在~8之间重输*/
return(c); /*返回选择项,主程序根据该数调用相应的函数*/
}
void Create(LinkList L)//创建链表节点
{
LinkList p=L,q;
if(L->next!=NULL)
{
p=L->next;
while(p->next!=NULL){
p=p->next;
}
}
int n;
cout<<"根据指定学生个数,逐个输入学生信息:"<<endl;
cout<<"学生个数n=";
cin>>n;
if(n<1){
cout<<"创建失败"<<endl;
return ;
}
for(int i=0;i<n;i++)//逐个添加数据
{
q=new LNode;
cout<<"第"<<i+1<<"个学生数据"<<endl<<"姓名:";
cin>>q->data.name;
cout<<"学号:";
cin>>q->data.no;
cout<<"成绩:";
cin>>q->data.price;
p->next=q;
p=q;
}
p->next=NULL;
cout<<"***操作成功***"<<endl;

}
void ShowAllDate(LinkList &L)//遍历链表所有记录,若空表即返回.
{
LinkList p=L->next;
if(L->next==NULL)
{
cout<<endl<<"    很遗憾,空表中没有任何记录可供显示!"<<endl;
return ;
}
cout<<"************ STUDENT ************"<<endl;
cout<<"  编号     姓名     学号     成绩"<<endl;
cout<<"---------------------------------"<<endl;
int i=0;
while(p!=NULL)
{
i++;
cout<<"   "<<i<<"      "<<p->data.name<<"      "<<p->data.no<<"      "<<p->data.price<<endl;
p=p->next;
}
cout<<"*********************************"<<endl;
cout<<"***操作成功***"<<endl;
}
void SearchByName(LinkList L)//通过姓名查找链表中的数据,模糊查询
{
LinkList p=L->next;
if(p==NULL)
{
cout<<endl<<"    很遗憾,空表中没有任何记录可供显示!"<<endl;
return ;
}
char s[20];
cout<<"根据姓名进行查找,返回此学生的学号和成绩"<<endl;
cout<<"请输入学生姓名:";
cin>>s;
int flag=0;
int i=0;
while(p!=NULL)
{
i++;
if(strstr(p->data.name,s))
{
if(flag==0)
{
cout<<"************ STUDENT ************"<<endl;
cout<<"  编号     姓名     学号     成绩"<<endl;
cout<<"---------------------------------"<<endl;
flag=1;
}
cout<<"   "<<i<<"      "<<p->data.name<<"      "<<p->data.no<<"      "<<p->data.price<<endl;
}
p=p->next;
}
if(flag==1)
{
cout<<"*********************************"<<endl;
}else{
cout<<"表中无此数据"<<endl;
return ;
}
cout<<"***操作成功***"<<endl;
}
void SearchByID(LinkList L)//通过编号查询,从链表头节点开始.
{
LinkList p=L->next;
if(p==NULL)
{
cout<<endl<<"    很遗憾,空表中没有任何记录可供显示!"<<endl;
return ;
}
int i;
cout<<"根据指定的位置可返回相应的信息(学号,姓名,成绩)"<<endl;
cout<<"请输入学生编号:";
cin>>i;
if(i<1)
{
cout<<"编号错误"<<endl;
return ;
}
int flag=0;
int j=0;
while(p!=NULL)
{
j++;
if(j==i)
{
cout<<"************ STUDENT ************"<<endl;
cout<<"  编号     姓名     学号     成绩"<<endl;
cout<<"---------------------------------"<<endl;
cout<<"   "<<i<<"      "<<p->data.name<<"      "<<p->data.no<<"      "<<p->data.price<<endl;
cout<<"*********************************"<<endl;
flag=1;
break;
}
p=p->next;
}
if(flag==0)
{
cout<<"编号错误"<<endl;
return ;
}
cout<<"***操作成功***"<<endl;
}
/*按ID号插入一组数据在节点里*/
void InsertByID(LinkList L)
{
LinkList p=L->next;
if(p==NULL)
{
cout<<endl<<"    很遗憾,空表中没有任何记录可供显示!"<<endl;
return ;
}
ShowAllDate(L);
int i;
cout<<"给定一个学生信息,插入到表中指定的位置"<<endl;
cout<<"请输入插入的位置:";
cin>>i;
if(i<1)
{
cout<<"位置不合法"<<endl;
return ;
}
int j=0,flag=0;
while(p!=NULL){
j++;
if(i==j){
flag=1;
break;
}
p=p->next;
}
if(flag==1){
Student e;
cout<<"请输入插入的数据:"<<endl;
cout<<"姓名:";
cin>>e.name;
cout<<"学号:";
cin>>e.no;
cout<<"成绩:";
cin>>e.price;
LinkList q=new LNode;
q->next=p->next;
p->next=q;//把新的节点插入两个节点之间
strcpy(q->data.name,e.name);
strcpy(q->data.no,e.no);
q->data.price=e.price;
cout<<"***操作成功***"<<endl;

}else{cout<<"位置不合法"<<endl;}
}
void DeleteByID(LinkList L)//删除指定位置学生数据
{
LinkList p=L->next;
if(p==NULL)
{
cout<<endl<<"    很遗憾,空表中没有任何记录可供显示!"<<endl;
return ;
}
ShowAllDate(L);
int i;
cout<<"删除指定位置的学生记录"<<endl;
cout<<"位置i=";
cin>>i;
if(i<1){
cout<<"位置不合法";
return ;
}
int j=0,flag=0;
while(p!=NULL)
{
j++;
if(i-1==j&&p->next!=NULL)//查询到指定位置的前一个节点,方便删后续节点
{
flag=1;
break;
}
p=p->next;
}
if(flag==0){
cout<<"位置不合法";
}else{
LinkList q=p->next->next;//被删节点的后续节点
delete p->next;
p->next=q;
cout<<"***操作成功***"<<endl;
}
}
/*遍历表,计数节点,也可以定义在线变量(在创建节点和删除节点的时候在线更新人数),而不是重复去遍历变量*/
void ShowNum(LinkList L)
{
LinkList p=L->next;
int i=0;
while(p!=NULL)
{
i++;
p=p->next;
}
cout<<"当前存档学生个数为:"<<i;
}
int main()
{
system("color 3e");             /*清屏*/
LinkList L;
InitList(L);
for(;;)               /*无限循环*/
{
switch(menu_select())               /*调用主菜单函数,返回值整数作开关语句的条件*/
{
case 1: Create(L);break;        //新建记录
case 2: ShowAllDate(L);break;          //显示全部记录
case 3: SearchByName(L);break;         //按姓名查找记录
case 4: SearchByID(L);break;         //按编号查找数据
case 5: InsertByID(L);break;        //插入记录
case 6: DeleteByID(L);break;    //通过ID删除记录
case 7: ShowNum(L);break;   //显示表中学生个数*/
case 8: exit(0);                    //程序结束*/
}

}
return 0;
}


五、流程图



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息