【數據結構與算法】單鏈表操作(C++)


  1 #include <stdio.h>
  2 #include <malloc.h>
  3 /*單鏈表節點定義*/
  4 typedef struct LNode {
  5     int data;            //data中存放節點數據域 
  6     struct LNode *next;   //指向后繼節點的指針
  7 }LNode;  //定義單鏈表節點類型
  8 
  9 /*例2.3開始*/
 10 /*A和B是兩個單鏈表(帶表頭結點),其中元素遞增有序,設計一個算法,將A 和B歸並成一個按元素值非遞減有序的鏈表C,C由A和B中的節點組成*/
 11 void mergeLNodeAsc(LNode *A, LNode *B, LNode *&C) {
 12     LNode *p = A->next;//p用來跟蹤A的最小值節點  A->next表示A鏈表的開始節點(頭結點的下一個) A遞增,所以p指向他表示指向A的最小節點,即用p來跟蹤A的最小節點
 13     LNode *q = B->next;//q來跟蹤B的最小值節點
 14     LNode *r; //r始終指向C的終端節點
 15     C = A;//用A的頭結點來做C的頭結點
 16     C->next = NULL;
 17     free(B); //B的頭結點無用,則釋放掉
 18     r = C;//r指向C 因為此時頭結點也是終端節點
 19     while (p!=NULL&&q!=NULL) {//當p和q都不空時,選取p和q所指節點中的較小者插入C的尾部
 20         if (p->data<=q->data) {
 21             printf("p小於q");
 22             r->next=p; //賦值C的節點
 23             p = p->next; //p前移一個
 24             r = r->next; //r前移一個
 25 
 26         }
 27         else {
 28             printf("q小於p");
 29             r->next = q;
 30             q = q->next;
 31             r = r->next;
 32         }
 33 
 34     }
 35     r->next = NULL; //這一個其實可以去掉 因為至少會剩下一個插入到C的尾部
 36     /*將還有剩余節點的鏈表插入到C的尾部*/
 37     if (p!=NULL) {
 38         r->next = p;
 39     }
 40     if (q != NULL) {
 41         r->next = q;
 42     }
 43 
 44 }
 45 /*例2.3結束*/
 46 
 47 
 48 /*尾插法建立鏈表C*/
 49 
 50 void createListR(LNode *&C,int a[],int n) {//要改變的變量用引用型
 51     LNode *s, *r;//s用來指向新申請的節點,r始終指向C的終端節點
 52     int i;
 53     C = (LNode *)malloc(sizeof(LNode));//申請C的頭結點空間
 54     C->next = NULL;
 55     r = C;//r指向頭結點,因為此時頭結點就是終端節點
 56     for (i = 0; i < n;++i) {
 57         s = (LNode *)malloc(sizeof(LNode)); //s指向新申請的節點
 58         s->data = a[i]; //用新申請的節點來接收a的一個元素
 59         r->next = s; //用r來接納新節點
 60         r = r->next; //用r指向終端節點,以便於接納下一個到來的節點
 61     }
 62     r->next = NULL;//數組a中所有的元素都已經裝入鏈表C中,C的終端節點的指針域為NULL C建立完成
 63 
 64 }
 65 
 66 /*頭插法建立鏈表C*/
 67 void createListF(LNode *&C, int a[], int n) {//要改變的變量用引用型
 68     LNode *s;//s用來指向新申請的節點
 69     int i;
 70     C = (LNode *)malloc(sizeof(LNode));//申請C的頭結點空間
 71     C->next = NULL;
 72     for (i = 0; i < n; ++i) {
 73         s = (LNode *)malloc(sizeof(LNode)); //s指向新申請的節點
 74         s->data = a[i]; //用新申請的節點來接收a的一個元素
 75         s->next = C->next;//s所指新節點的指針域next指向C的開始節點
 76         C->next = s;//頭結點的指針域next指向s節點,使得s稱為新的開始節點
 77     }
 78 
 79 }
 80 
 81 /*歸並為遞減的單鏈表*/
 82 
 83 void  mergeLNodeDesc(LNode *A,LNode *B,LNode *&C) {
 84 
 85     LNode *p = A->next;
 86     LNode *q = B->next;
 87     LNode *s;
 88     C = A;
 89     C->next = NULL;
 90     free(B);
 91     while (p!=NULL&&q!=NULL) {
 92         if (p->data<=q->data) {
 93             s = p;
 94             p=p->next;
 95             s->next=C->next;
 96             C->next = s;
 97         }
 98         else {
 99             s = q;
100             q = q->next;
101             s->next = C->next;
102             C->next = s;
103         }
104     }
105     /*必須將剩余元素逐個插入C的頭部才能得到最終的遞減序列*/
106 
107     while (p!=NULL) {
108         s = p;
109         p = p -> next;
110         s ->next = C->next;
111         C->next = s;
112     }
113     while (q != NULL) {
114         s = q;
115         q = q->next;
116         s->next = C->next;
117         C->next = s;
118     }
119 
120 }
121 
122 /*例2.4開始*/
123 /*查找鏈表C中是否存在一個值為x的節點,若存在,則刪除該節點並返回1,否則返回0*/
124 
125 int findAndDelete(LNode *C,int x) {
126     LNode *p, *q; /*q用來接納刪除的元素 ,p用來指向C的節點*/
127     p = C;
128     while (p->next!=NULL) {
129 
130         if (p->next->data ==x) {/*查找的是要刪除節點的額前驅節點*/
131             break;
132         }
133         p = p->next; /*如果當前不是要找的節點 則p向后移*/
134     }
135     /*沒找到*/
136     if (p->next ==NULL) {
137         return 0;
138     
139     }
140     else {
141         /*刪除部分開始*/
142         q = p->next;
143         p->next = p->next->next;
144         free(q);
145         /*刪除部分結束*/
146         return 1;
147     }
148 
149 }
150 /*例2.4結束*/
151 
152 /*打印鏈表中的元素*/
153 void showLNode(LNode *C) {
154     LNode *p;
155     p = C;
156     while (p->next!=NULL) {
157         printf("C的數據為:%d\n", p->next->data);
158         p = p->next;
159     }
160     
161 }
162 
163 void main() {
164 
165     LNode *C;
166     int a[] = { 1,2,3,4 };
167     int n = 4;
168     createListF(C, a, n);
169     showLNode(C);// 4 3 2 1 
170     findAndDelete(C, 2);
171     showLNode(C);// 4 3 1
172 
173 
174     LNode *D;
175     int b[] = { 1,2,3,4,5,6 };
176     int m = 6;
177     createListR(D, b, m);
178     showLNode(D); // 1 2 3 4 5 6
179 
180     findAndDelete(D, 8);
181     showLNode(D);// 1 2 3 4 5 6
182     printf("開始合並數組");
183 
184     LNode *M;
185     int m1[] = { 1,3,5 };
186     int m2 = 3;
187     createListR(M, m1, m2);
188     LNode *N;
189     int n1[] = { 2,4,6 };
190     int n2 = 3;
191     createListR(N, n1, n2);
192     LNode *O;
193     mergeLNodeDesc(M, N,O);
194     showLNode(O);// 6 5 4 3 2 1
195 
196     LNode *Q;
197     int q1[] = { 1,3,5 };
198     int q2 = 3;
199     createListR(Q, q1, q2);
200     LNode *R;
201     int r1[] = { 2,4,6 };
202     int r2 = 3;
203     createListR(R, r1, r2);
204     LNode *P;
205     mergeLNodeAsc(Q, R, P);
206     showLNode(P);// 1 2 3 4 5 6
207 }

 


免責聲明!

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



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