飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3174|回复: 0

编程马拉松(12)链表

[复制链接]

该用户从未签到

发表于 2007-8-25 07:53:09 | 显示全部楼层 |阅读模式
还是11题的内容,但用连表方式实现

  1. #include <iOStream>  
  2. using namespace std;  
  3. struct test  
  4. {  
  5.     int number;  
  6.     char name[20];
  7.         float shuxue;
  8.         float yuwen;
  9.         float yingyu;
  10.         float wule;
  11.         float huaxue;
  12.         float zongfen()
  13.         {
  14.                 return shuxue+yuwen+wule+huaxue+yingyu;
  15.         };
  16.     test *next;
  17.         const struct test& operator=(const struct test &a)//这里用到了,运算符重载,以后会讲。
  18.         {
  19.                 number = a.number;
  20.                 strcpy(name, a.name);
  21.                 shuxue = a.shuxue;
  22.                 yuwen = a.yuwen;
  23.                 yingyu = a.yingyu;
  24.                 wule = a.wule;
  25.                 huaxue = a.huaxue;
  26.                 return *this;
  27.         }
  28. };  
  29. test *head;//创建一个全局的引导进入链表的指针  
  30.   
  31. test *create()  //输入数据
  32. {  
  33.     test *ls;//节点指针  
  34.     test *le;//链尾指针  
  35.     ls = new test;//把ls指向动态开辟的堆内存地址  
  36.     cout<<"请输入第一个学生数据,输入所有项为0退出"<<endl;  
  37.                                 cout<<"学号:";
  38.                         cin>>ls->number;
  39.                                 cout<<"姓名:";
  40.                         cin>>ls->name;
  41.                                 cout<<"数学:";
  42.                         cin>>ls->shuxue;
  43.                                 cout<<"语文:";
  44.                         cin>>ls->yuwen;
  45.                                 cout<<"英语:";
  46.                         cin>>ls->yingyu;
  47.                                 cout<<"物理:";
  48.                         cin>>ls->wule;
  49.                                 cout<<"化学:";
  50.                         cin>>ls->huaxue;  
  51.     head=NULL;//进入的时候先不设置head指针指向任何地址,因为不知道是否一上来就输入null跳出程序  
  52.     le=ls;//把链尾指针设置成刚刚动态开辟的堆内存地址,用于等下设置le->next,也就是下一个节点的位置  
  53.     while(ls->number!=0)//创建循环条件为ls->number的值不是null,用于循环添加节点  
  54.     {  
  55.         if(head==NULL)//判断是否是第一次进入循环  
  56.         {  
  57.             head=ls;//如果是第一次进入循环,那么把引导进入链表的指针指向第一次动态开辟的堆内存地址  
  58.         }  
  59.         else  
  60.         {  
  61.             le->next=ls;//如果不是第一次进入那么就把上一次的链尾指针的le->next指向上一次循环结束前动态创建的堆内存地址  
  62.         }  
  63.         le=ls;//设置链尾指针为当前循环中的节点指针,用于下一次进入循环的时候把上一次的节点的next指向上一次循环结束前动态创建的堆内存地址  
  64.         ls=new test;//为下一个节点在堆内存中动态开辟空间  
  65.     cout<<"请输入下一个学生数据,输入所有项为0退出"<<endl;  
  66.                                 cout<<"学号:";
  67.                         cin>>ls->number;
  68.                                 cout<<"姓名:";
  69.                         cin>>ls->name;
  70.                                 cout<<"数学:";
  71.                         cin>>ls->shuxue;
  72.                                 cout<<"语文:";
  73.                         cin>>ls->yuwen;
  74.                                 cout<<"英语:";
  75.                         cin>>ls->yingyu;
  76.                                 cout<<"物理:";
  77.                         cin>>ls->wule;
  78.                                 cout<<"化学:";
  79.                         cin>>ls->huaxue;  
  80.     }  
  81.     le->next=NULL;//把链尾指针的next设置为空,因为不管如何循环总是要结束的,设置为空才能够在循环显链表的时候不至于死循环  
  82.     delete ls;//当结束的时候最后一个动态开辟的内存是无效的,所以必须清除掉  
  83.     return head;//返回链首指针  
  84. }  
  85. void showl(test *head)  //显示表
  86. {  
  87.         test * p = head;
  88.     //cout<<"链首指针:"<<head<<endl;  
  89.     while(p)//以内存指向为null为条件循环显示先前输入的内容  
  90.     {  
  91.         cout<<p->number<<"   "
  92.                         <<p->name<<"   "
  93.                         <<p->shuxue<<"   "
  94.                         <<p->yuwen<<"   "
  95.                         <<p->yingyu<<"   "
  96.                         <<p->wule<<"   "
  97.                         <<p->huaxue
  98.                         <<endl;  
  99.         p=p->next;  
  100.     }  
  101. }  
  102. void deletel(test *&head,int number)//(删除)这里如果参数换成test *head,意义就完全不同了,head变成了复制而不是原有链上操作了,特别注意,很多书上都不对这里  
  103. {  
  104.     test *point;//判断链表是否为空  
  105.     if(head==NULL)  
  106.     {  
  107.         cout<<"链表为空,不能进行删除工作!";  
  108.         return;  
  109.     }  
  110.   
  111.     int derror=1;//设置找不到的情况的条件,预先设置为真  
  112.     test *check=head;  
  113.     while(check)//利用循环进行查找  
  114.     {  
  115.         if (check->number==number)  
  116.         {  
  117.             derror=0;//条件转为假  
  118.         }  
  119.         check=check->next;  
  120.     }  
  121.     if(derror)//如果为假就跳出函数  
  122.     {  
  123.         return;  
  124.     }  
  125.   
  126.     if(head->number==number)//判删除的节点是否为首节点  
  127.     {  
  128.         point=head;  
  129.         cout<<"删除点是链表第一个节点位置!";  
  130.         head=head->next;//重新设置引导指针  
  131.         delete point;  
  132.         return;  
  133.     }  
  134.     for(test *mp=head;mp->next;mp=mp->next)  
  135.     {  
  136.         if(mp->next->number==number)  
  137.         {  
  138.             point=mp->next;  
  139.             mp->next=point->next;  
  140.             delete point;  
  141.             return;  
  142.         }  
  143.     }  
  144. }  
  145.   
  146. void insterl(int number)  //插入
  147. {  
  148.     test *indata=new test;  
  149.     cout<<"插入学生成绩"<<endl;  
  150.         cout<<"学号:";
  151.                 cin>>indata->number;
  152.         cout<<"姓名:";
  153.                 cin>>indata->name;
  154.         cout<<"数学:";
  155.                 cin>>indata->shuxue;
  156.         cout<<"语文:";
  157.                 cin>>indata->yuwen;
  158.         cout<<"英语:";
  159.                 cin>>indata->yingyu;
  160.         cout<<"物理:";
  161.                 cin>>indata->wule;
  162.         cout<<"化学:";
  163.                 cin>>indata->huaxue;
  164.   
  165.     if(head==NULL)//链表为空的情况下插入  
  166.     {  
  167.         head=indata;  
  168.         indata->next=NULL;  
  169.         return;  
  170.     }  
  171.   
  172.     int ierror=1;//设置找不到的情况的条件,预先设置为真  
  173.     test *le;  
  174.     test *check=head;  
  175.     while(check)//利用循环进行查找  
  176.     {  
  177.         if (check->number==number)  
  178.         {  
  179.             ierror=0;//条件转为假  
  180.         }  
  181.         le=check;  
  182.         check=check->next;  
  183.     }  
  184.     if(ierror)  
  185.     {  
  186.         //cout<<le->number;  
  187.         le->next=indata;  
  188.         indata->next=NULL;  
  189.         return;  
  190.     }  
  191.   
  192.    if(head->number==number)//检测是否是在第一个节点处插入  
  193.     {  
  194.         indata->next=head;  
  195.         head=indata;  
  196.         return;  
  197.     }  
  198.   
  199.     for(test *mp=head;mp->next;mp=mp->next)//在链表中间插入  
  200.     {  
  201.         if(mp->next->number==number)  
  202.         {  
  203.             indata->next=mp->next;  
  204.             mp->next=indata;  
  205.             return;  
  206.         }  
  207.     }  
  208.   
  209. }  
  210. void paixu(test *head)//排序
  211. {
  212.         test *tmp0=new test;
  213.        

  214.         test *tmp1=head;
  215.         while(tmp1)
  216.         {
  217.                 test *tmp2=tmp1->next;
  218.                 while(tmp2)
  219.                 {
  220.                         if(tmp1->zongfen()>tmp2->zongfen())
  221.                         {
  222.                                 *tmp0=*tmp1;
  223.                                 *tmp1=*tmp2;
  224.                                 *tmp2=*tmp0;
  225.                         }

  226.                         tmp2=tmp2->next;
  227.                 }
  228.                 tmp1=tmp1->next;
  229.         }
  230.         delete tmp0;
  231.         tmp0 = head;
  232.         while(tmp0)  
  233.     {  
  234.         cout<<tmp0->number<<"   "
  235.                         <<tmp0->name<<"   "
  236.                         <<tmp0->shuxue<<"   "
  237.                         <<tmp0->yuwen<<"   "
  238.                         <<tmp0->yingyu<<"   "
  239.                         <<tmp0->wule<<"   "
  240.                         <<tmp0->huaxue<<"  "
  241.                         <<tmp0->zongfen()<<"  "
  242.                         <<tmp0->zongfen()/5.0<<"  "
  243.                         <<endl;  
  244.         tmp0=tmp0->next;  
  245.     }
  246.        
  247. }

  248.        

  249. void main()  
  250. {  
  251.        
  252.         int mu=1;
  253.         int err=1;
  254.        
  255.         while (err!=0)
  256.         {
  257.         cout<<"\n1--输入学生成绩(学号,姓名,数学,语文,英语,物理,化学)\n"
  258.                 <<"2--插入学生成绩(学号,姓名,数学,语文,英语,物理,化学)\n"
  259.                 <<"3--输入学号删除学生成绩\n"
  260.                 <<"4--按总分排序输出(学号,姓名,数学,语文,英语,物理,化学,总分,平均分)\n"
  261.                 <<"0--退出\n"
  262.                 <<"请选择你的操作:";
  263.         cin>>mu;
  264.         switch(mu)
  265.         {
  266.         case 1://第一次输入
  267.                         if(head==NULL)//用来判断是不是第一次输入数据。
  268.                         {
  269.                         head=create();//调用创建        
  270.                         showl(head);
  271.                         err=1;
  272.                         break;
  273.                         }
  274.                         cout<<"您不是第一次输入数据,请选择插入\n\n\n";
  275.                         break;
  276.         case 2://插入数据
  277.                         showl(head);
  278.                         int ip;  
  279.                         cout<<"请输入在那个学号前面,如果没有这个学号将在最后插入"<<endl;  
  280.                         cin>>ip;  
  281.                         insterl(ip);
  282.                         err=1;
  283.                         break;
  284.         case 3://删除数据
  285.                         showl(head);
  286.                     int dp;  
  287.                         cout<<"请输入删除点如果找不到就跳出函数"<<endl;  
  288.                         cin>>dp;  
  289.                         deletel(head,dp);//调用删除
  290.                         err=1;
  291.                         break;
  292.         case 4://排序
  293.                 if(head!=NULL)
  294.                 {
  295.                         paixu(head);
  296.                         showl(head);
  297.                         err=1;
  298.                         break;
  299.                 }
  300.                 cout<<"学生成绩数据为空,请输入数据在排序。";
  301.                 break;
  302.         case 0: //退出
  303.                         err=0;
  304.                         break;
  305.         default://错误
  306.                         cout<<"输入错误,请重新输入\n";
  307.                         err=-1;
  308.                         break;
  309.                        
  310.         }
  311.     }
  312. }

复制代码
PYG19周年生日快乐!
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表