实现单链表的各种基本操作

  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<<"******************************************************************************\n";
188         cout<<"  1. 建立空链表;                          2. 在表中输入指定个数的数据元素\n";
189         cout<<"  3. 在第i个元素的前插入一个元素;         4. 逐个显示表中数据元素\n";
190         cout<<"  5. 查找位序为i的元素,返回其值;         6. 依值查找,返回其位序\n";
191         cout<<"  7. 删除表中第i个元素;                   8. 返回值最大的元素及其在表中位置\n";
192         cout<<"  9. 就地逆置;                            10. 删除表中所有值为item的数据元素\n";
193         cout<<"  11.删除单链表中值最小的数据元素;        0. 退出\n";
194         cout<<"*******************************************************************************\n";
195 
196         cout<<"请选择:";
197         cin>>choose;
198         switch(choose)
199         {
200         case 1:      //建立一个单链表
201             if(InitList_L(L))
202                 cout<<"成功建立链表!\n\n";
203             break;
204         case 2:     //使用后插法创建单链表
205             cout<<"请输入一个数,代表元素的个数:";
206             cin>>n;
207             CreateList_L(L,n);
208             cout<<"成功创建链表!\n\n";
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<<"个位置\n\n";
215             else
216                 cout<<"插入失败!\n\n";
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<<".\n"<<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<<".\n"<<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<<"已被删除.\n"<<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<<".\n"<<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<<"从链表中删除.\n"<<endl;
280                 else
281                     cout<<"此链表没有"<<x<<"这个元素.\n"<<endl;
282             }
283             break;
284         case 11:    //删除单链表中值最小的数据元素
285             if(delMinList_L(L,i,x))
286                 cout<<"已经删除了该表中"<<i<<"位置上的最小元素"<<x<<".\n"<<endl;
287             else
288                 cout<<"当前为空表"<<endl;
289             break;
290         }
291     }
292     return 0;
293 }

 

posted @ 2018-03-29 23:58  霜雪千年  阅读(3133)  评论(0编辑  收藏  举报