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 }