freesoft 发表于 2007-8-25 07:53:09

编程马拉松(12)链表

还是11题的内容,但用连表方式实现

#include <iostream>
using namespace std;
struct test
{
    int number;
    char name;
        float shuxue;
        float yuwen;
        float yingyu;
        float wule;
        float huaxue;
        float zongfen()
        {
                return shuxue+yuwen+wule+huaxue+yingyu;
        };
    test *next;
        const struct test& operator=(const struct test &a)//这里用到了,运算符重载,以后会讲。
        {
                number = a.number;
                strcpy(name, a.name);
                shuxue = a.shuxue;
                yuwen = a.yuwen;
                yingyu = a.yingyu;
                wule = a.wule;
                huaxue = a.huaxue;
                return *this;
        }
};
test *head;//创建一个全局的引导进入链表的指针

test *create()//输入数据
{
    test *ls;//节点指针
    test *le;//链尾指针
    ls = new test;//把ls指向动态开辟的堆内存地址
    cout<<"请输入第一个学生数据,输入所有项为0退出"<<endl;
                                cout<<"学号:";
                        cin>>ls->number;
                                cout<<"姓名:";
                        cin>>ls->name;
                                cout<<"数学:";
                        cin>>ls->shuxue;
                                cout<<"语文:";
                        cin>>ls->yuwen;
                                cout<<"英语:";
                        cin>>ls->yingyu;
                                cout<<"物理:";
                        cin>>ls->wule;
                                cout<<"化学:";
                        cin>>ls->huaxue;
    head=NULL;//进入的时候先不设置head指针指向任何地址,因为不知道是否一上来就输入null跳出程序
    le=ls;//把链尾指针设置成刚刚动态开辟的堆内存地址,用于等下设置le->next,也就是下一个节点的位置
    while(ls->number!=0)//创建循环条件为ls->number的值不是null,用于循环添加节点
    {
      if(head==NULL)//判断是否是第一次进入循环
      {
            head=ls;//如果是第一次进入循环,那么把引导进入链表的指针指向第一次动态开辟的堆内存地址
      }
      else
      {
            le->next=ls;//如果不是第一次进入那么就把上一次的链尾指针的le->next指向上一次循环结束前动态创建的堆内存地址
      }
      le=ls;//设置链尾指针为当前循环中的节点指针,用于下一次进入循环的时候把上一次的节点的next指向上一次循环结束前动态创建的堆内存地址
      ls=new test;//为下一个节点在堆内存中动态开辟空间
    cout<<"请输入下一个学生数据,输入所有项为0退出"<<endl;
                                cout<<"学号:";
                        cin>>ls->number;
                                cout<<"姓名:";
                        cin>>ls->name;
                                cout<<"数学:";
                        cin>>ls->shuxue;
                                cout<<"语文:";
                        cin>>ls->yuwen;
                                cout<<"英语:";
                        cin>>ls->yingyu;
                                cout<<"物理:";
                        cin>>ls->wule;
                                cout<<"化学:";
                        cin>>ls->huaxue;
    }
    le->next=NULL;//把链尾指针的next设置为空,因为不管如何循环总是要结束的,设置为空才能够在循环显链表的时候不至于死循环
    delete ls;//当结束的时候最后一个动态开辟的内存是无效的,所以必须清除掉
    return head;//返回链首指针
}
void showl(test *head)//显示表
{
        test * p = head;
    //cout<<"链首指针:"<<head<<endl;
    while(p)//以内存指向为null为条件循环显示先前输入的内容
    {
      cout<<p->number<<"   "
                        <<p->name<<"   "
                        <<p->shuxue<<"   "
                        <<p->yuwen<<"   "
                        <<p->yingyu<<"   "
                        <<p->wule<<"   "
                        <<p->huaxue
                        <<endl;
      p=p->next;
    }
}
void deletel(test *&head,int number)//(删除)这里如果参数换成test *head,意义就完全不同了,head变成了复制而不是原有链上操作了,特别注意,很多书上都不对这里
{
    test *point;//判断链表是否为空
    if(head==NULL)
    {
      cout<<"链表为空,不能进行删除工作!";
      return;
    }

    int derror=1;//设置找不到的情况的条件,预先设置为真
    test *check=head;
    while(check)//利用循环进行查找
    {
      if (check->number==number)
      {
            derror=0;//条件转为假
      }
      check=check->next;
    }
    if(derror)//如果为假就跳出函数
    {
      return;
    }

    if(head->number==number)//判删除的节点是否为首节点
    {
      point=head;
      cout<<"删除点是链表第一个节点位置!";
      head=head->next;//重新设置引导指针
      delete point;
      return;
    }
    for(test *mp=head;mp->next;mp=mp->next)
    {
      if(mp->next->number==number)
      {
            point=mp->next;
            mp->next=point->next;
            delete point;
            return;
      }
    }
}

void insterl(int number)//插入
{
    test *indata=new test;
    cout<<"插入学生成绩"<<endl;
        cout<<"学号:";
                cin>>indata->number;
        cout<<"姓名:";
                cin>>indata->name;
        cout<<"数学:";
                cin>>indata->shuxue;
        cout<<"语文:";
                cin>>indata->yuwen;
        cout<<"英语:";
                cin>>indata->yingyu;
        cout<<"物理:";
                cin>>indata->wule;
        cout<<"化学:";
                cin>>indata->huaxue;

    if(head==NULL)//链表为空的情况下插入
    {
      head=indata;
      indata->next=NULL;
      return;
    }

    int ierror=1;//设置找不到的情况的条件,预先设置为真
    test *le;
    test *check=head;
    while(check)//利用循环进行查找
    {
      if (check->number==number)
      {
            ierror=0;//条件转为假
      }
      le=check;
      check=check->next;
    }
    if(ierror)
    {
      //cout<<le->number;
      le->next=indata;
      indata->next=NULL;
      return;
    }

   if(head->number==number)//检测是否是在第一个节点处插入
    {
      indata->next=head;
      head=indata;
      return;
    }

    for(test *mp=head;mp->next;mp=mp->next)//在链表中间插入
    {
      if(mp->next->number==number)
      {
            indata->next=mp->next;
            mp->next=indata;
            return;
      }
    }

}
void paixu(test *head)//排序
{
        test *tmp0=new test;
       

        test *tmp1=head;
        while(tmp1)
        {
                test *tmp2=tmp1->next;
                while(tmp2)
                {
                        if(tmp1->zongfen()>tmp2->zongfen())
                        {
                                *tmp0=*tmp1;
                                *tmp1=*tmp2;
                                *tmp2=*tmp0;
                        }

                        tmp2=tmp2->next;
                }
                tmp1=tmp1->next;
        }
        delete tmp0;
        tmp0 = head;
        while(tmp0)
    {
      cout<<tmp0->number<<"   "
                        <<tmp0->name<<"   "
                        <<tmp0->shuxue<<"   "
                        <<tmp0->yuwen<<"   "
                        <<tmp0->yingyu<<"   "
                        <<tmp0->wule<<"   "
                        <<tmp0->huaxue<<""
                        <<tmp0->zongfen()<<""
                        <<tmp0->zongfen()/5.0<<""
                        <<endl;
      tmp0=tmp0->next;
    }
       
}

       

void main()
{
       
        int mu=1;
        int err=1;
       
        while (err!=0)
        {
        cout<<"\n1--输入学生成绩(学号,姓名,数学,语文,英语,物理,化学)\n"
                <<"2--插入学生成绩(学号,姓名,数学,语文,英语,物理,化学)\n"
                <<"3--输入学号删除学生成绩\n"
                <<"4--按总分排序输出(学号,姓名,数学,语文,英语,物理,化学,总分,平均分)\n"
                <<"0--退出\n"
                <<"请选择你的操作:";
        cin>>mu;
        switch(mu)
        {
        case 1://第一次输入
                        if(head==NULL)//用来判断是不是第一次输入数据。
                        {
                        head=create();//调用创建        
                        showl(head);
                        err=1;
                        break;
                        }
                        cout<<"您不是第一次输入数据,请选择插入\n\n\n";
                        break;
        case 2://插入数据
                        showl(head);
                        int ip;
                        cout<<"请输入在那个学号前面,如果没有这个学号将在最后插入"<<endl;
                        cin>>ip;
                        insterl(ip);
                        err=1;
                        break;
        case 3://删除数据
                        showl(head);
                  int dp;
                        cout<<"请输入删除点如果找不到就跳出函数"<<endl;
                        cin>>dp;
                        deletel(head,dp);//调用删除
                        err=1;
                        break;
        case 4://排序
                if(head!=NULL)
                {
                        paixu(head);
                        showl(head);
                        err=1;
                        break;
                }
                cout<<"学生成绩数据为空,请输入数据在排序。";
                break;
        case 0: //退出
                        err=0;
                        break;
        default://错误
                        cout<<"输入错误,请重新输入\n";
                        err=-1;
                        break;
                       
        }
    }
}

页: [1]
查看完整版本: 编程马拉松(12)链表