数据结构实验一 线性表的顺序存储实验



 
本课主题: 实验一线性表的顺序存储实验

教学目的: 掌握顺序表的定义及操作的C语言实现方法

教学重点: 顺序表的操作的C语言实现方法

教学难点: 顺序表的操作的C语言实现方法

实验内容:
利用顺序表完成一个班级的一个学期的所有课程的管理:能够增加、删除、修改学生的成绩记录。

实验要求:
在上机前写出全部源程序。

上一课,举了一个例子,主要实现了一个顺序表的相关操作,现在做个小小的实验,即实现一个小小的学生成绩管理系统。

需求如下:

用顺序表实现一个完成一个班级的一个学期的所有课程的管理:能够增加、删除、修改学生的成绩记录。

假设学生有学号id,班级名class_name,学期term, 性别sex,姓名name,语文chinese,英语english,数学maths等字段。

系统分析:

系统有增加,删除,修改,查找等操作,都放在一个主界面选择进行。

由于时间关系,暂时使用C/C++混编了。本来我是学java的干脆用类设计的。

后来想了想为方便大家观摩,学习。还是用面向过程好了,这样大家也方便!



Java代码 复制代码  收藏代码
  1. 源码如下(实现是在VC++6.0下编译通过):  
  2. // student.cpp : Defines the entry point for the console application.  
  3. /** 说明:本程序主要实现学生成绩管理的相关操作,如添加,删除,修改,查询等**** 
  4. ***************************************************************************** 
  5. *****************************************************************************/  
  6. #include "stdafx.h"  
  7. #include "iostream.h"  
  8. #include <stdio.h>  
  9. #include <stdlib.h>   
  10. #include <string.h>  
  11.    
  12. struct student  
  13. {    
  14.   char term[10]; // 学期  
  15.   char  class_name[10]; // 班级名  
  16.   int id;  // 学号id  
  17.   char name[30]; // 姓名   
  18.   char sex[2];  // 性别    
  19.   float chinese; // 语文  
  20.   float  english; // 英语   
  21.   float  maths; // 数学   
  22. };  
  23. typedef struct student DataType; //  指定struct student为DataType  
  24. struct SeqList  
  25. {  
  26.  int MAXLENGTH;     // 顺序表中最大元素的个数  
  27.  int count;         // 存放线性表中元素的个数count <= MAXLENGTH  
  28.  DataType* element;  // element[0], element[1], ..., element[n - 1]存放线性表中的元素  
  29. };   
  30. typedef struct SeqList *MySeqList;    
  31. // 初始化并创建空顺序表  
  32. MySeqList initSeqList(int m);  
  33. // 判断线性表是否为空  
  34. int isEmptySeqList(MySeqList mySeqList);  
  35. // 在顺序表中求某元素的下标  
  36. int locateSeqList(MySeqList mySeqList, int id);  
  37. // 在顺序表中修改值  
  38. int updateSeqList(MySeqList mySeqList, int id);  
  39. // 顺序表的插入(元素p之前插入)  
  40. int insertPreSeqList(MySeqList mySeqList, int p, DataType x);  
  41. // 顺序表的插入(元素p之后插入)  
  42. int insertNextSeqList(MySeqList mySeqList, int p, DataType x);  
  43. // 顺序表的删除(根据下标删除)  
  44. int deleteSeqList(MySeqList mySeqList, int p);  
  45. // 顺序表的删除(根据元素值删除)  
  46. int deleteSeqListByValue(MySeqList mySeqList, int id);  
  47. // 将顺序表表示的线性表逆置  
  48. int reverseSeqList(MySeqList mySeqList);  
  49. /* 
  50. * 删除线性表中所有值为x的值 
  51. * 我给出的算法,在一个线性表中实现,设置了2个游标 
  52. */  
  53. int deleteAllVSeqList(MySeqList mySeqList, DataType x);  
  54. // 求出下标为i的元素的前驱和后继  
  55. int findPrePostSeqList(MySeqList mySeqList, int i, DataType &m, DataType &n);  
  56. // 顺序表实现部分:找出值为x的元素的前驱和后继的存储位置(即下标)  
  57. int locatePrePostSeqList(MySeqList mySeqList, DataType x, int &i, int &j);   
  58. // 输出线性表的元素值  
  59. void printSeqList(MySeqList &mySeqList);   
  60. // 根据学生id,输出线性表的元素值  
  61. void printSeqListById(MySeqList &mySeqList,int id);  
  62. // 在顺序表中修改值  
  63. int updateSeqList(MySeqList mySeqList, int id)  
  64. {  
  65.  int iRc = locateSeqList(mySeqList, id);  
  66.  if (iRc == -1)  
  67.  {  
  68.   printf("不存在指定下标!\n");  
  69.   return (0);  
  70.  }  
  71.     
  72.  cout<<"class name:";          
  73.  cin>>mySeqList->element[iRc].class_name;  
  74.              
  75.  cout<<"term: ";  
  76.  cin>>mySeqList->element[iRc].term;  
  77.  cout<<"学号: ";  
  78.  cin>>mySeqList->element[iRc].id;  
  79.  cout<<"name: ";  
  80.  cin>>mySeqList->element[iRc].name;  
  81.  cout<<"sex: ";  
  82.  cin>>mySeqList->element[iRc].sex;   
  83.  cout<<"english: ";  
  84.  cin>>mySeqList->element[iRc].english;   
  85.       
  86.  cout<<"chinese: ";  
  87.  cin>>mySeqList->element[iRc].chinese;   
  88.  cout<<"maths: ";  
  89.  cin>>mySeqList->element[iRc].maths;      
  90.    
  91.  return 1;  
  92. }  
  93.    
  94. // 功能: 创建空顺序表  
  95. MySeqList initSeqList(int m)  
  96. {  
  97.  MySeqList mySeqList = (MySeqList)malloc(sizeof(struct SeqList)); // 分配内存空间  
  98.  if (mySeqList != NULL)  
  99.  {  
  100.   mySeqList->element = (DataType*)malloc(sizeof(DataType) * m);   // 为里面的元素分配m个DataType大小的内存空间,相当于初始化了一个长度为m的数组  
  101.   if (mySeqList->element)  
  102.   {  
  103.    mySeqList->MAXLENGTH = m;  // 如果创建了元素,MAXLENGTH为最大元素的个数  
  104.    mySeqList->count = 0;  // 空表长度为0  
  105.    return (mySeqList);  
  106.   }  
  107.   else  
  108.    free(mySeqList);        // 记得要手动释放空间,否则很容易产生内存泄漏  
  109.  }  
  110.  printf("内存空间不足,请关闭一些程序,然后再试!\n"); // 存储分配失败,提示空间不足  
  111.  return NULL;  
  112. }   
  113. // 功能: 判断线性表是否为空  
  114. int isEmptySeqList(MySeqList mySeqList)  
  115. {  
  116.  return (mySeqList->count ==0);  
  117. }   
  118. // 功能:在顺序表中求某元素的下标,没有查找到,则返回-1  
  119. int locateSeqList(MySeqList mySeqList, int id)  
  120. {   
  121.  for (int i = 0; i < mySeqList->count; ++i)  
  122.   if (mySeqList->element[i].id == id)             // 传入一个元素x,查找到后返回下标i  
  123.    return (i);  
  124.  return (-1);  
  125. }   
  126. // 功能:顺序表的pos下标前面插入,插入成功返回1,失败返回0  
  127. int insertPreSeqList(MySeqList mySeqList, int pos, DataType x)  
  128. {  
  129.  ++mySeqList->count;  
  130.  if (mySeqList->count > mySeqList->MAXLENGTH)      // 溢出  
  131.  {  
  132.   --mySeqList->count;       
  133.   printf("表产生了溢出!\n");  
  134.   return (0);  
  135.  }  
  136.  if (pos < 0 || pos >= mySeqList->count)         // 不存在下标为pos的元素  
  137.  {  
  138.   --mySeqList->count;  
  139.   printf("不存在指定下标!\n");  
  140.   return (0);  
  141.  }   
  142.  for (int i = mySeqList->count - 1; i != pos; --i)  
  143.   mySeqList->element[i] = mySeqList->element[i - 1]; // 插入位置及之后的元素均后移一个位置  
  144.  mySeqList->element[i] = x;                          // 插入元素x  
  145.  return (1);  
  146. }   
  147. // 功能:顺序表的pos下标后面插入,插入成功返回1,失败返回0  
  148. int insertNextSeqList(MySeqList mySeqList, int pos, DataType x)  
  149. {  
  150.  if (pos < 0 || pos >= mySeqList->count)  
  151.  {  
  152.   printf("不存在指定下标!\n");  
  153.   return (0);  
  154.  }  
  155.  ++mySeqList->count;  
  156.  if (mySeqList->count >= mySeqList->MAXLENGTH)  
  157.  {  
  158.   --mySeqList->count;  
  159.   printf("表产生了溢出!\n");  
  160.   return (0);  
  161.  }  
  162.    
  163.  for (int i = mySeqList->count - 1; i != pos + 1; --i)  
  164.   mySeqList->element[i] = mySeqList->element[i - 1];  // 同样地,把pos+1插入位置及之后的元素均后移一个位置  
  165.  mySeqList->element[i] = x;                           // 插入元素x  
  166.  return (1);  
  167. }   
  168. // 功能:顺序表的删除(根据下标删除)  
  169. int deleteSeqList(MySeqList  mySeqList, int pos)  
  170. {  
  171.  if (pos < 0 || pos >= mySeqList->count)      // 不存在下标为pos的元素,注意下标范围是从0到count-1  
  172.  {  
  173.   printf("不存在指定下标!\n");  
  174.   return (0);  
  175.  }  
  176.    
  177.  for (int i = pos; i < mySeqList->count - 1; ++i)  
  178.   mySeqList->element[i] = mySeqList->element[i + 1];   // 被删除元素之后的元素均前移一个位置  
  179.  --mySeqList->count;                                  // 元素个数减1  
  180.  return (1);  
  181. }   
  182. // 功能:根据元素值删除,实现顺序表的删除  
  183. int deleteSeqListByValue(MySeqList mySeqList, int id)  
  184. {  
  185.  int pos = locateSeqList(mySeqList, id);  
  186.  if (pos == -1)  
  187.  {  
  188.   printf("不存在指定下标!\n");  
  189.   return (0);  
  190.  }  
  191.  deleteSeqList(mySeqList, pos);  
  192.  return (1);  
  193. }   
  194.     
  195. /* 
  196. * 功能:删除线性表中所有学生ID为x的值 
  197. */  
  198. int deleteAllSeqListByValue(MySeqList mySeqList, int x)  
  199. {  
  200.  if (mySeqList->count == 0)  
  201.  {  
  202.   printf("该表为空!\n");  
  203.   return (0);  
  204.  }  
  205.  for (int i = 0; i != mySeqList->count; ++i)  
  206.  {  
  207.     
  208.   if (mySeqList->element[i].id == x )  
  209.   {     
  210.       deleteSeqListByValue(mySeqList,x);             // 删除x,删除后要将下标减少1  
  211.       i--;  
  212.   }  
  213.  }  
  214.  return (1);  
  215. }  
  216.   
  217. /* 
  218. * 功能:删除线性表中所有值为x的值的另一种算法 
  219.  
  220. */  
  221. int deleteAllVSeqList(MySeqList mySeqList, int x)  
  222. {  
  223.  if (mySeqList->count == 0)  
  224.  {  
  225.   printf("该表为空!\n");  
  226.   return (0);  
  227.  }  
  228.  int p = 0, q = 0;  
  229.  while (mySeqList->element[p].id != x && p != mySeqList->count - 1)  // 跳过开始不是x的元素  
  230.  {  
  231.   ++p;  
  232.   ++q;  
  233.  }  
  234.  for (; p != mySeqList->count - 1; ++p)                            // 遍历元素,不遍历最后一个元素(为了防止越界)  
  235.  {  
  236.   while (mySeqList->element[p].id == x && p != mySeqList->count - 1// 如果元素是x,则游标p后移(用while处理多个x连续的情况)  
  237.   {  
  238.    ++p;  
  239.   }  
  240.   if (p != mySeqList->count - 1)  
  241.   {  
  242.    mySeqList->element[q] = mySeqList->element[p];  
  243.    ++q;  
  244.   }  
  245.  }  
  246.  if (mySeqList->element[mySeqList->count - 1].id != x)  
  247.  {  
  248.   mySeqList->element[q] = mySeqList->element[mySeqList->count - 1];  
  249.   ++q;  
  250.  }  
  251.  mySeqList->count = q;  
  252.  return (1);  
  253. }   
  254.    
  255. // 功能:找出值为x的元素的前驱和后继的存储位置(即下标)  
  256. int locatePrePostSeqList(MySeqList mySeqList, int x, int &i, int &j)  
  257. {  
  258.  int k = locateSeqList(mySeqList, x);  
  259.  if (k == -1)  
  260.   return (0);  
  261.  if (k == 0)  
  262.   i = -1;  
  263.  else  
  264.   i = k - 1;  
  265.  if (k == mySeqList->count - 1)  
  266.   j = -1;  
  267.  else  
  268.   j = k + 1;  
  269.  return (1);  
  270. }   
  271. // 输出线性表的元素值  
  272. void printSeqList(MySeqList &mySeqList)  
  273. {  
  274.     
  275.  for (int i = 0; i < mySeqList->count; ++i)  // 输出线性表的元素值  
  276.  {  
  277.    cout<< "学期:" << mySeqList->element[i].term << ",班级名:" << mySeqList->element[i].class_name    ;  
  278.    cout<< "学号:" << mySeqList->element[i].id << ",姓名:" << mySeqList->element[i].name << ",性别:" << mySeqList->element[i].sex ;  
  279.    cout<< "语文:" << mySeqList->element[i].chinese<< ",英语:" << mySeqList->element[i].english << ",数学:" << mySeqList->element[i].maths ;  
  280.    cout<<endl;  
  281.  }  
  282.  cout << endl;  
  283. }  
  284. // 根据学生id,输出线性表的元素值  
  285. void printSeqListById(MySeqList &mySeqList,int id)   
  286. {  
  287.     
  288.  for (int i = 0; i < mySeqList->count; ++i)  // 输出线性表的元素值  
  289.  {  
  290.    if (id == mySeqList->element[i].id)  
  291.    {  
  292.      cout<< "学期:" << mySeqList->element[i].term << ",班级名:" << mySeqList->element[i].class_name;  
  293.      cout<< "学号:" << mySeqList->element[i].id << ",姓名:" << mySeqList->element[i].name << ",性别:" << mySeqList->element[i].sex ;  
  294.      cout<< "语文:" << mySeqList->element[i].chinese<< ",英语:" << mySeqList->element[i].english << ",数学:" << mySeqList->element[i].maths ;  
  295.      cout<<endl;  
  296.      break;  
  297.    }  
  298.  }  
  299.    
  300. }  
  301. int main(int argc, char* argv[])  
  302. {  
  303. /* 
  304.  MySeqList mySeqList = initSeqList(20); // 初始化一个长20的表 
  305.  for (int i = 0; i < 20; ++i)           // 对表进行赋值 
  306.  { 
  307.   mySeqList->count++;                   // 对表进行赋值  
  308.   mySeqList->element[i] = i;            // 对表进行赋值  
  309.  } 
  310. */  
  311. MySeqList mySeqList = initSeqList(20); // 初始化一个长20的表  
  312. L:   
  313.    system("cls");  
  314.    cout<< "*********************学生成绩管理系统*****************"<<endl;  
  315.    cout<< "***************1.添加学生信息 2.查找学生信息**********"<<endl;  
  316.    cout<< "***************3.删除学生信息 4.修改学生信息**********"<<endl;  
  317.    cout<< "***************5.退出学生系统               **********"<<endl;  
  318.    int i;     
  319.    cout<<"请选择一个操作(1-5):";  
  320.    cin>>i;   
  321.    if (i == 1)  
  322.    {      
  323.      mySeqList->count = 1;  
  324.   int iRc = 0;  
  325.   while(true&&mySeqList->count<20)  
  326.   {      
  327.        cout<<endl<<"请输入要添加的学生成绩信息(输入*退出添加):"<<endl;    
  328.     cout<<"class name:";      
  329.       
  330.     cin>>mySeqList->element[iRc].class_name;  
  331.           if (strcmp(mySeqList->element[iRc].class_name,"*") == 0)   
  332.     {    
  333.      mySeqList->count--;     // 此处要减1,请思考为什么要减1哦。  
  334.      goto L;  
  335.     }  
  336.              
  337.        cout<<"term: ";  
  338.     cin>>mySeqList->element[iRc].term;  
  339.     cout<<"学号: ";  
  340.     cin>>mySeqList->element[iRc].id;  
  341.     cout<<"name: ";  
  342.     cin>>mySeqList->element[iRc].name;  
  343.        cout<<"sex: ";  
  344.     cin>>mySeqList->element[iRc].sex;   
  345.        cout<<"english: ";  
  346.     cin>>mySeqList->element[iRc].english;   
  347.       
  348.         cout<<"chinese: ";  
  349.     cin>>mySeqList->element[iRc].chinese;   
  350.         cout<<"maths: ";  
  351.     cin>>mySeqList->element[iRc].maths;     
  352.             
  353.     cout << "添加学生成绩信息成绩ok."<<endl;  
  354.           printSeqList(mySeqList);  
  355.           mySeqList->count++;  
  356.           iRc++;  
  357.   }  
  358.            
  359.    }  
  360.    else if (i == 2)  
  361.    {  
  362. L4:  
  363.        cout<<"请输入要查找的学生ID:"<<endl;  
  364.     int  sid;  
  365.     cin>>sid;  
  366.     if (locateSeqList(mySeqList,sid) != -1)   
  367.     {  
  368.      cout<<"查询学号为"<<sid<<"的学生成绩ok."<<endl;  
  369.            printSeqListById(mySeqList,sid);  
  370.     }  
  371.     else  
  372.     {  
  373.      cout<<"查询学生成绩error,可能不存在学号为"<<sid<<"的学生."<<endl;  
  374.     }  
  375.     int iopselect;  
  376.     cout<<endl<<"还要继续查询吗,按0返回主菜单,否则继续此操作?"<<endl;  
  377.     cin>>iopselect;  
  378.     if (iopselect == 0)   
  379.      goto L ;  
  380.     else   
  381.         goto L4;  
  382.      
  383.    }  
  384.    else if (i == 3)  
  385.    {  
  386. L1:  
  387.        cout<<"请输入要删除的学生ID:"<<endl;  
  388.     int stu_id;  
  389.     cin>>stu_id;  
  390.       
  391.        if (deleteSeqListByValue(mySeqList,stu_id) == 1)   
  392.          cout<<"删除学生成绩ok."<<endl;  
  393.     else  
  394.    cout<<"删除学生成绩error."<<endl;  
  395.     printSeqList(mySeqList);  
  396.     int iop;  
  397.     cout<<endl<<"还要继续删除吗,按0返回主菜单,否则继续此操作?"<<endl;  
  398.     cin>>iop;  
  399.     if (iop == 0)   
  400.      goto L ;  
  401.     else   
  402.         goto L1;  
  403.    }  
  404.    else if (i == 4)  
  405.    {  
  406. L3:  
  407.     cout<<"请输入要修改的学生ID:"<<endl;  
  408.        int id;  
  409.     cin>>id;  
  410.     if(updateSeqList(mySeqList,id) ==1)   
  411.          cout << "修改学生成绩信息成绩ok."<<endl;  
  412.     else  
  413.          cout << "修改学生成绩信息成绩error."<<endl;  
  414.        printSeqList(mySeqList);  
  415.     int iselect;  
  416.     cout<<endl<<"还要继续修改吗,按0返回主菜单,否则继续此操作?"<<endl;  
  417.     cin>>iselect;  
  418.     if (iselect == 0)   
  419.      goto L ;  
  420.     else   
  421.         goto L3;  
  422.    }  
  423.    else if (i == 5)  
  424.    {     
  425.     system("cls");  
  426.     cout<<"你已经退出本系统,欢迎下次再使用."<<endl;   
  427.    }  
  428.       
  429.  return 0;  
  • 7
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值