zoukankan      html  css  js  c++  java
  • 实现单链表的各种基本操作

      1 #include<iostream>
      2 using namespace std;
      3 
      4 #define OK 1
      5 #define ERROR 0
      6 #define OVERFLOW -2
      7 typedef int Status;        //Status 是函数返回值类型,其值是函数结果状态代码。
      8 typedef int ElemType;     //ElemType 为可定义的数据类型,此设为int类型
      9 
     10 typedef struct LNode
     11 {
     12     ElemType data;    //结点的数据域
     13     struct LNode *next;        //结点的指针域
     14 }LNode,*LinkList;  //LinkList为指向结构体LNode的指针类型
     15 
     16 
     17 Status InitList_L(LinkList &L){    //算法2.5 单链表的初始化
     18     //构造一个空的单链表L
     19     L=new LNode;    //生成新结点作为头结点,用头指针L指向头结点
     20     L->next=NULL;    //头结点的指针域置空
     21     return OK;
     22 }
     23 
     24 Status ListInsert_L(LinkList &L,int i,ElemType &e){ //算法2.8 单链表的插入
     25     //在带头结点的单链表L中第i个位置之前插入元素e
     26     int j;
     27     LinkList p,s;
     28     p=L;j=0;
     29     while(p && j<i-1){p=p->next;++j;} //刚好指向第i-1个节点
     30     if(!p||j>i-1)    return ERROR;    //i大于表长+1或者小于1  当p不为空时如果i小于1的话则插入失败,如果p为空的话表明i大于表长
     31     s=new LNode;    //生成新结点s  p指向当前第i-1的节点位置
     32     s->data=e;        //将结点s的数据域置为e
     33     s->next=p->next; //将结点s插入L中
     34     p->next=s;
     35     return OK;
     36 }//ListInsert_L
     37 
     38 void CreateList_F(LinkList &L,int n){ //算法2.10 (前插法)创建单链表
     39     //逆位序输入n个元素的值,建立到头结点的单链表L
     40     LinkList p;
     41     L=new LNode;
     42     L->next=NULL;     //先建立一个带头结点的空链表
     43     cout<<"请输入 "<<n<<" 个数(以空格隔开,按回车结束):";
     44     for(int i=n;i>0;--i){
     45         p=new LNode;     //生成新结点
     46         cin>>p->data;   //输入元素值
     47         p->next=L->next;
     48         L->next=p;  //插入到表头
     49     }
     50 }//CreateList_F
     51 
     52 void CreateList_L(LinkList &L,int n){ //算法2.11 (后插法)创建单链表
     53     //正位序输入n个元素的值,建立到头结点的单链表L
     54     LinkList r,p;
     55     L=new LNode;
     56     L->next=NULL; //先建立一个带头结点的空链表
     57     r=L;          //尾指针r指向头结点
     58     cout<<"请输入 "<<n<<" 个数(以空格隔开,按回车结束):";
     59     for(int i=0;i<n;i++){
     60         p=new LNode;     //生成新结点
     61         cin>>p->data;      //输入元素值
     62         p->next=NULL;
     63         r->next=p;     //插入到表尾
     64         r=p;            //r指向新的尾结点   r始终指向当前节点
     65     }
     66 }//CreateList_L
     67 
     68 Status findValList_L(LinkList L,int i,ElemType &indexVal){    //5.查找位序为i的元素,返回其值
     69     LinkList p=L->next;//指向第一个结点
     70     int j=1;//标记当前节点的位置为1
     71     while(p && j<i){    //找第i个节点
     72         p=p->next;      //循环链表
     73         ++j;             //同步p节点的位置
     74     }
     75     if(!p||j>i)return ERROR; // i值不合法:!p表示i大于表长;j>i表示i小于1这种情况
     76     indexVal=p->data;//把第i个节点的值赋值给indexVal
     77     return OK;   //返回1,表示查找成功
     78 }
     79 
     80 Status findIndexList_L(LinkList L,ElemType val,int &index){     //6.依值查找,返回其位序
     81     LinkList p=L->next;//指向第一个节点
     82     int j=1;          //同时标记起始位置为1
     83     while(p){
     84         if(p->data==val){  //依次比较
     85             index=j;      //如果相等的话就把当前p的位置
     86             return OK;    //返回1表示查找成功
     87         }
     88         p=p->next;       //循环链表
     89         j++;            //同步p指针的位置
     90     }
     91     return ERROR;       //前面没有返回的话,这时返回失败,表示找不到
     92 }
     93 
     94 Status deleteIndexList_L(LinkList &L,int i,ElemType &indexVal){      //7.删除表中第i个元素
     95     LinkList p=L;  //这时要指向头节点,因为当i=1时,下面的循环进不去,也就是if判断不成功,这时进行删除节点操作
     96     int j=0;        //同步p节点的位置
     97     while(p && j<i-1){   //找到第i-1个节点
     98         p=p->next;      //循环链表
     99         j++;            //同步当前节点
    100     }
    101     if(!p||j>i-1)return ERROR;  // !p表示i大于链表表长,j>i-1表示i小于1,此时p不为空
    102     LinkList q=p->next;     //q节点指向第i个节点
    103     if(!q)return ERROR;  //根据条件,此处应该判断p的后继是否为空即为i这个特殊情况,举个例子,表长j为3时,i为4,到此句的时候就成立,表示表长加1这个位置没有元素,返回删除失败
    104     indexVal=q->data;
    105     p->next=q->next;     //链接链表
    106     delete q;          //删除第i个节点
    107     return OK;          //表示删除成功
    108 }
    109 
    110 Status findMaxList_L(LinkList L,int &index,int &MaxVal){    //8.返回值最大的元素及其在表中位置,引用最大值
    111     if(L->next==NULL)return ERROR;       //如果是空链表,则返回0
    112     LinkList p=L->next->next;           //将p指向第二个节点
    113     int j=2;                          //同时同步指针位置
    114     MaxVal=L->next->data;           //标记第一个节点的值为最大值
    115     index=1;                         //同步最大值的位置
    116     while(p){
    117         if(p->data>MaxVal){      //当前p的数据与MaxVal比较
    118             MaxVal=p->data;     //赋值
    119             index=j;           //标记位置
    120         }
    121         p=p->next;     //循环链表
    122         j++;            //同步p的位置
    123     }
    124     return OK;          //表示查找成功
    125 }
    126 
    127 Status reverseList_L(LinkList &L){   //9.就地逆置算法
    128     LinkList p=L->next,q;       //先用p来保存原来的第一个节点
    129     L->next=NULL;         //仍利用原链表的首地址,此时将头结点指向空
    130     if(!p)return ERROR;    //如果第一个节点为空,则为空表
    131     while(p){
    132         q=p->next;          //先用q来保存p节点的next域,用来移动原来的链表
    133         p->next=L->next;      //仍用L空间,每次插在头结点后面的位置
    134         L->next=p;            //L(带头节点)时刻指向当前节点p
    135         p=q;                  //将p重新指向原表中p的后继
    136     }
    137     return OK;             //表示逆序成功
    138 }
    139 
    140 Status delItemList_L(LinkList &L,ElemType item){   //10.删除表中所有值为item的数据元素
    141     LinkList p=L,q;           //指向头节点,临时指针q
    142     bool f=false;             //标记链表中是否有item这个元素
    143     while(p){
    144         if((q=p->next)&&(q->data==item)){  //先判断是否有这个p->next这个元素
    145             if(!f)f=true;//有的话只标记一次就好
    146             p->next=q->next;   //链接链表
    147             delete q;
    148         }
    149         else p=p->next;//否则才移动p
    150     }
    151     if(!f)return ERROR;   //标记该表中没有此元素
    152     return OK;
    153 }
    154 
    155 Status delMinList_L(LinkList &L,int &indexMin,ElemType &minVal){    //11.实现删除单链表中值最小的数据元素
    156     LinkList p=L->next;
    157     if(!p)return ERROR;   //空表
    158     minVal=p->data;   //标记第一个节点为最小值
    159     indexMin=1;         //同步最小值节点位序
    160     p=p->next;    //指向第二个节点
    161     int j=2;   //同步p节点的位序
    162     while(p){    //先去找最小值
    163         if(p->data<minVal){     //依次比较
    164             minVal=p->data;
    165             indexMin=j;
    166         }
    167         p=p->next;       //循环链表
    168         j++;
    169     }
    170     LinkList q=L,tmp;
    171     for(int i=1;i<indexMin;i++)  //找到要删除节点的前驱
    172         q=q->next;
    173     tmp=q->next;   //保存要删除的节点
    174     q->next=tmp->next;  //链接链表
    175     delete tmp;  // 删除节点
    176     return OK;  //删除成功
    177 }
    178 int main()
    179 {
    180     int i,n,choose;
    181     ElemType x;
    182     LinkList L,p;
    183 
    184     choose=-1;
    185     while(choose!=0)
    186     {
    187         cout<<"******************************************************************************
    ";
    188         cout<<"  1. 建立空链表;                          2. 在表中输入指定个数的数据元素
    ";
    189         cout<<"  3. 在第i个元素的前插入一个元素;         4. 逐个显示表中数据元素
    ";
    190         cout<<"  5. 查找位序为i的元素,返回其值;         6. 依值查找,返回其位序
    ";
    191         cout<<"  7. 删除表中第i个元素;                   8. 返回值最大的元素及其在表中位置
    ";
    192         cout<<"  9. 就地逆置;                            10. 删除表中所有值为item的数据元素
    ";
    193         cout<<"  11.删除单链表中值最小的数据元素;        0. 退出
    ";
    194         cout<<"*******************************************************************************
    ";
    195 
    196         cout<<"请选择:";
    197         cin>>choose;
    198         switch(choose)
    199         {
    200         case 1:      //建立一个单链表
    201             if(InitList_L(L))
    202                 cout<<"成功建立链表!
    
    ";
    203             break;
    204         case 2:     //使用后插法创建单链表
    205             cout<<"请输入一个数,代表元素的个数:";
    206             cin>>n;
    207             CreateList_L(L,n);
    208             cout<<"成功创建链表!
    
    ";
    209             break;
    210         case 3:  //单链表的插入
    211             cout<<"请输入两个数,分别代表插入的位置和插入数值(用空格间隔,最后回车):";
    212             cin>>i>>x;     //输入i和x,i代表插入的位置,x代表插入的数值
    213             if(ListInsert_L(L,i,x))
    214                    cout<<"成功将"<<x<<"插在第"<<i<<"个位置
    
    ";
    215             else
    216                 cout<<"插入失败!
    
    ";
    217             break;
    218         case 4:     //单链表的输出
    219             p=L->next;//指向第一个节点
    220             if(!p)
    221                 cout<<"当前为空链表"<<endl<<endl;
    222             else{
    223                 cout<<"现在链表里的数分别是:";
    224                 i=0;
    225                 while(p){//循环直到为空
    226                 i++;
    227                 cout<<p->data<<"";
    228                 p=p->next;
    229                 }
    230                 cout<<"共有"<<i<<"个元素。"<<endl<<endl;
    231             }
    232             break;
    233         case 5:    //查找位序为i的元素,返回其值
    234             cout<<"请输入一个你想要查找该元素的位序:";
    235             cin>>i;
    236             if(findValList_L(L,i,x))
    237                 cout<<"位序为"<<i<<"的元素为"<<x<<".
    "<<endl;
    238             else
    239                 cout<<"输入位序序号不在链表节点序号范围内"<<endl<<endl;
    240             break;
    241         case 6:   //依值查找,返回其位序
    242             int index;
    243             cout<<"请输入要查找的元素:";
    244             cin>>x;
    245             if(findIndexList_L(L,x,index))
    246                 cout<<"查找元素"<<x<<"在链表中的位序为"<<index<<".
    "<<endl;
    247             else
    248                 cout<<"此元素不在该链表中"<<endl<<endl;
    249             break;
    250         case 7:    //删除表中第i个元素
    251             cout<<"请输入删除表中元素的位置:";
    252             cin>>i;
    253             if(deleteIndexList_L(L,i,x))
    254                 cout<<""<<i<<"个位置的元素"<<x<<"已被删除.
    "<<endl;
    255             else
    256                 cout<<"输入位置不在当前链表节点序号范围内"<<endl<<endl;
    257             break;
    258         case 8:     //返回值最大的元素及其在表中位置
    259             ElemType MaxVal;
    260             if(findMaxList_L(L,i,MaxVal))
    261                 cout<<"当前链表中最大的元素为"<<MaxVal<<",其位置为"<<i<<".
    "<<endl;
    262             else
    263                 cout<<"当前为空链表"<<endl<<endl;
    264             break;
    265         case 9:    //就地逆置
    266             if(reverseList_L(L))
    267                 cout<<"就地成功逆置链表"<<endl<<endl;
    268             else
    269                 cout<<"此表为空链表"<<endl<<endl;
    270 
    271             break;
    272         case 10:    //删除表中所有值为item的数据元素
    273             if(L->next==NULL)
    274                 cout<<"当前为空链表"<<endl<<endl;
    275             else{
    276                 cout<<"请输入要删除链表的一个元素:";
    277                 cin>>x;
    278                 if(delItemList_L(L,x))
    279                     cout<<"删除成功,已经将元素"<<x<<"从链表中删除.
    "<<endl;
    280                 else
    281                     cout<<"此链表没有"<<x<<"这个元素.
    "<<endl;
    282             }
    283             break;
    284         case 11:    //删除单链表中值最小的数据元素
    285             if(delMinList_L(L,i,x))
    286                 cout<<"已经删除了该表中"<<i<<"位置上的最小元素"<<x<<".
    "<<endl;
    287             else
    288                 cout<<"当前为空表"<<endl;
    289             break;
    290         }
    291     }
    292     return 0;
    293 }
  • 相关阅读:
    git ssh keys
    git 修改 email
    git 撤销commit
    企微调试模式
    ORACLE 根据某个字段固定值进行分区
    Apache FtpClient login失败
    Oracle序列
    Oracle merage into
    Oracle all_tables 以及常用sql
    性能优化-使用高性能的库fastutil
  • 原文地址:https://www.cnblogs.com/acgoto/p/8673398.html
Copyright © 2011-2022 走看看