實現單鏈表的各種基本操作


  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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM