實現單鏈表的各種基本運算
阿新 • • 發佈:2018-03-30
類型 兩個 如果 OS 鏈接 函數 最大 space 新的
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,inti,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; 71 while(p && j<i){ //找第i個節點 72 p=p->next; 73 ++j; 74 } 75 if(!p||j>i)return ERROR;//i值不合法i大於表長或者是i小於1 76 indexVal=p->data; 77 return OK; 78 } 79 80 Status findIndexList_L(LinkList L,ElemType val,int &index){ //6.依值查找,返回其位序 81 LinkList p=L->next;//指向第一個節點 82 int j=1; 83 while(p){ 84 if(p->data==val){ 85 index=j; 86 return OK; 87 } 88 p=p->next; 89 j++; 90 } 91 return ERROR; 92 } 93 94 Status deleteIndexList_L(LinkList &L,int i){ //7.刪除表中第i個元素 95 int j=0; 96 LinkList p=L; //這時要指向頭節點,因為當i=1時,下面的循環進不去,也就是if判斷不成功,進行刪除節點操作 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大於表長,或者是 102 LinkList q=p->next;//q節點指向第i個節點 103 if(!q)return ERROR; //根據條件,此處應該判斷p的後繼是否為空即為i這個特殊情況,舉個例子,表長為3時,i為4,到此句的時候就成立,表示表長加1這個位置沒有元素 104 p->next=q->next;//鏈接鏈表 105 delete q; 106 return OK; 107 } 108 109 Status findMaxList_L(LinkList L,int &index,int &MaxVal){ //8.返回值最大的元素及其在表中位置,引用最大值 110 if(L->next==NULL)return ERROR;//如果是空鏈表,則返回0 111 LinkList p=L->next->next;//將p指向第二個節點 112 int j=2;//同時同步指針位置 113 MaxVal=L->next->data;//標記第一個節點的值為最大值 114 index=1;//同步最大值的位置 115 while(p){ 116 if(p->data>MaxVal){ 117 MaxVal=p->data; 118 index=j; 119 } 120 p=p->next; 121 j++; 122 } 123 return OK; 124 } 125 126 Status reverseList_L(LinkList &L){ //9.就地逆置算法 127 LinkList p=L->next,q; //先用p來保存原來的第一個節點 128 L->next=NULL;//仍利用原表的空間,此時將頭結點指向空 129 if(!p)return ERROR; 130 while(p){ 131 q=p->next;//先用q來保存p節點的next域,用來移動原來的鏈表 132 p->next=L->next; //仍用L空間,使用插在頭結點後面的位置也就是前插法 133 L->next=p; //L(帶頭節點)時刻指向當前節點p 134 p=q; //將p重新指向原表中後繼 135 } 136 return OK; 137 } 138 139 Status delItemList_L(LinkList &L,ElemType item){ //10.刪除表中所有值為item的數據元素 140 LinkList p=L,q;//指向頭節點,臨時指針q 141 bool f=false;//標記鏈表中是否有item這個元素 142 while(p){ 143 if((q=p->next)&&(q->data==item)){ //先判斷是否有這個p->next這個元素 144 if(!f)f=true;//有的話只標記一次就好 145 p->next=q->next; //鏈接鏈表 146 delete q; 147 } 148 else p=p->next;//否則才移動p 149 } 150 if(!f)return ERROR; //標記該表中沒有此元素 151 return OK; 152 } 153 154 int main() 155 { 156 int i,n,choose; 157 ElemType x; 158 LinkList L,p; 159 160 choose=-1; 161 while(choose!=0) 162 { 163 cout<<"******************************************************************************\n"; 164 cout<<" 1. 建立空鏈表; 2. 在表中輸入指定個數的數據元素\n"; 165 cout<<" 3. 在第i個元素的前插入一個元素; 4. 逐個顯示表中數據元素\n"; 166 cout<<" 5. 查找位序為i的元素,返回其值; 6. 依值查找,返回其位序\n"; 167 cout<<" 7. 刪除表中第i個元素; 8. 返回值最大的元素及其在表中位置\n"; 168 cout<<" 9. 就地逆置; 10. 刪除表中所有值為item的數據元素\n"; 169 cout<<" 0. 退出\n"; 170 cout<<"*******************************************************************************\n"; 171 172 cout<<"請選擇:"; 173 cin>>choose; 174 switch(choose) 175 { 176 case 1: //建立一個單鏈表 177 if(InitList_L(L)) 178 cout<<"成功建立鏈表!\n\n"; 179 break; 180 case 2: //使用後插法創建單鏈表 181 cout<<"請輸入一個數,代表元素的個數:"; 182 cin>>n; 183 CreateList_L(L,n); 184 cout<<"成功創建鏈表!\n\n"; 185 break; 186 case 3: //單鏈表的插入 187 cout<<"請輸入兩個數,分別代表插入的位置和插入數值(用空格間隔,最後回車):"; 188 cin>>i>>x; //輸入i和x,i代表插入的位置,x代表插入的數值 189 if(ListInsert_L(L,i,x)) 190 cout<<"成功將"<<x<<"插在第"<<i<<"個位置\n\n"; 191 else 192 cout<<"插入失敗!\n\n"; 193 break; 194 case 4: //單鏈表的輸出 195 p=L->next;//指向第一個節點 196 if(!p) 197 cout<<"當前為空鏈表"<<endl<<endl; 198 else{ 199 cout<<"現在鏈表裏的數分別是:"; 200 i=0; 201 while(p){//循環直到為空 202 i++; 203 cout<<p->data<<","; 204 p=p->next; 205 } 206 cout<<"共有"<<i<<"個元素。"<<endl<<endl; 207 } 208 break; 209 case 5: //查找位序為i的元素,返回其值 210 cout<<"請輸入一個你想要查找該元素的位序:"; 211 cin>>i; 212 if(findValList_L(L,i,x)) 213 cout<<"位序為"<<i<<"的元素為"<<x<<".\n"<<endl; 214 else 215 cout<<"輸入位序序號不在鏈表節點序號範圍內"<<endl<<endl; 216 break; 217 case 6: //依值查找,返回其位序 218 int index; 219 cout<<"請輸入要查找的元素:"; 220 cin>>x; 221 if(findIndexList_L(L,x,index)) 222 cout<<"查找元素"<<x<<"在鏈表中的位序為"<<index<<".\n"<<endl; 223 else 224 cout<<"此元素不在該鏈表中"<<endl<<endl; 225 break; 226 case 7: //刪除表中第i個元素 227 cout<<"請輸入刪除表中元素的位置:"; 228 cin>>i; 229 if(deleteIndexList_L(L,i)) 230 cout<<"第"<<i<<"個位置的元素已被刪除.\n"<<endl; 231 else 232 cout<<"輸入位置不在當前鏈表節點序號範圍內"<<endl<<endl; 233 break; 234 case 8: //返回值最大的元素及其在表中位置 235 ElemType MaxVal; 236 if(findMaxList_L(L,i,MaxVal)) 237 cout<<"當前鏈表中最大的元素為"<<MaxVal<<",其位置為"<<i<<".\n"<<endl; 238 else 239 cout<<"當前為空鏈表"<<endl<<endl; 240 break; 241 case 9: //就地逆置 242 if(reverseList_L(L)) 243 cout<<"就地成功逆置鏈表"<<endl<<endl; 244 else 245 cout<<"此表為空鏈表"<<endl<<endl; 246 247 break; 248 case 10: //刪除表中所有值為item的數據元素 249 if(L->next==NULL) 250 cout<<"當前為空鏈表"<<endl<<endl; 251 else{ 252 cout<<"請輸入要刪除鏈表的一個元素:"; 253 cin>>x; 254 if(delItemList_L(L,x)) 255 cout<<"刪除成功,已經將元素"<<x<<"從鏈表中刪除.\n"<<endl; 256 else 257 cout<<"此鏈表沒有"<<x<<"這個元素.\n"<<endl; 258 } 259 break; 260 } 261 } 262 return 0; 263 }
實現單鏈表的各種基本運算