經典演算法之兩個有序單鏈表合併
阿新 • • 發佈:2018-12-29
/************************ author's email:[email protected] date:2017.12.31 單鏈表應用 ************************/ /* A和B是兩個單鏈表(帶表頭結點),其中元素遞增有序。設計一個演算法,將A和B歸成一 個按元素值非遞減有序的連結串列C,C由A和B中的結點組成。 */ #include <iostream> using namespace std; #define maxSize 10 typedef struct LNode { int data; struct LNode *next; }LNode; void createListR(LNode *&p, int *a, int n);//尾插法構造單鏈表 void printList(LNode *p); void createListF(LNode *&p, int *a, int n);//頭插法構造單鏈表 void bubbleSort(LNode *L);//按結點值的大小氣泡排序,使之呈遞增序列 void merge(LNode *A, LNode *B, LNode *&C);//將A和B合併成非遞減有序的C,利用尾插法 void main() { int a[maxSize] = { 15,46,47,29,19,23,68,79,115,784 }; int b[maxSize] = { 45,11,78,49,56,113,456,741,999,35 }; LNode *A,*B,*C; A = (LNode*)malloc(sizeof(LNode)); A->next = NULL; B = (LNode*)malloc(sizeof(LNode)); B->next = NULL; C = (LNode*)malloc(sizeof(LNode)); C->next = NULL; cout << "頭插法結果為:" << endl; createListF(A, a, maxSize);//頭插法 printList(A->next); cout << "尾插法結果為:" << endl; createListR(B, b, maxSize);//尾插法 printList(B->next); cout << "連結串列A遞增排序後為:" << endl; bubbleSort(A); printList(A->next); cout << "連結串列B遞增排序後為:" << endl; bubbleSort(B); printList(B->next); cout << "將A和B合併成非遞減有序的C連結串列後:" << endl; merge(A, B, C); printList(C->next); } void createListR(LNode *&p, int *a, int n) {//尾插法構造單鏈表 LNode *s, *r; int i; r = p; for (i = 0; i < n; ++i) { s = (LNode*)malloc(sizeof(LNode)); s->data = a[i]; r->next = s; r = r->next; } r->next = NULL; } void printList(LNode *p) {//輸出連結串列 if (p->next == NULL) cout << "連結串列為空!" << endl; else { while (p != NULL) { cout << p->data << ' '; p = p->next; } cout << endl; } } void createListF(LNode *&p, int *a, int n) {//頭插法構造連結串列 LNode *s; int i; for (i = 0; i < n; ++i) { s = (LNode*)malloc(sizeof(LNode)); s->data = a[i]; s->next = p->next; p->next = s; } } void bubbleSort(LNode *L) { LNode *p, *tail, *next; int temp; if (L->next == NULL) cout << "連結串列為空!" << endl; else { for (p = L->next; p != NULL; p = p->next) /*尾指標初始化*/ ; tail = p; while (tail != L->next) { for (p = L->next; p->next != tail; p = p->next) { next = p->next; if (p->data > next->data) /*相鄰節點比較,資料交換*/ { temp = p->data; p->data = next->data; next->data = temp; } } tail = p; /* p->next == tail,即把tail往前移動一位 */ } } } void merge(LNode *A, LNode *B, LNode *&C) { LNode *p = A->next; //p來跟蹤A的最小值結點 LNode *q = B->next; //q來跟蹤B的最小值結點 LNode *r; //r始終指向C的終端結點 C = A; //A的頭結點來做C的頭結點 //C->next = NULL; free(B); r = C; while (p != NULL&&q != NULL) {//當p、q都不為空時,選取p與q所指結點中的較小者插入C的尾部 //尾插法建立單鏈表 if (p->data <= q->data) { r->next = p; p = p->next; r = r->next; } else { r->next = q; q = q->next; r = r->next; } } //以下兩個if語句將剩餘的結點連結在C的尾部 if (p != NULL) r->next = p; if (q != NULL) r->next = q; }