資料結構——演算法之(033)(兩個有序單鏈表合併為一個有序的單鏈表)
阿新 • • 發佈:2019-01-07
【申明:本文僅限於自我歸納總結和相互交流,有紕漏還望各位指出。 聯絡郵箱:[email protected]】
題目:
兩個有序單鏈表合併為一個有序的單鏈表(預設升序)
題目分析:
1、因為兩個連結串列都是有序的,所以首先要記錄那個連結串列頭最小
2、大致思想是用一個虛擬節點順序連線兩個連結串列中的節點,並且順移兩個連結串列中頭指標,讓其一直 指向第一個未被連線的節點
演算法實現:
#include <stdio.h> #include <stdlib.h> typedef struct _list_node { int key; struct _list_node *next; }list_node; void *list_insert(list_node *head, int key) { list_node *p = head; while(p->next != NULL) p = p->next; list_node *node = calloc(1, sizeof(list_node)); node->key = key; node->next = NULL; p->next = node; } list_node *list_init() { list_node *head = calloc(1, sizeof(list_node)); head->key = 0; head->next = NULL; return head; } /* ** 帶頭結點的連結串列合併:大致思想是用一個虛擬節點順序(升序)串聯兩個連結串列中的 ** 節點,每次記錄當前節點的位置 ** h1-->: 1---4---7 ---12 ** h2-->: 3---9---13---14 */ list_node *list_merger(list_node *h1, list_node *h2) { if(!h1) return h2; if(!h2) return h1; /* ** @head節點記錄兩個連結串列中較小的那個頭結點 */ list_node * head; if (h1->key > h2->key) { head = h2; h2 = h2->next; } else { head = h1; h1 = h1->next; } list_node * current = head; while (h1 != NULL || h2 != NULL) { /* ** current節點一直指向最後連線的節點 ** (1)如果連結串列@h1先遍歷完,直接把連結串列@h2後面節點連線到@current後面 */ if (h1 == NULL || (h2 != NULL && h1->key > h2->key)) { current->next = h2; /*把@h2節點連線到@current節點後面*/ current = current->next; /*調整@current指標,指向最新連線的節點*/ h2 = h2->next; /*過濾掉已經被連線過的節點*/ } else { current->next = h1; current = current->next; h1 = h1->next; } } current->next = NULL; return head->next; } void list_display(list_node *head) { list_node *p = head->next; printf("list:"); int count = 0; while(p != NULL) { printf(" %d", p->key); p = p->next; count++; } printf(" --->[%d]", count); printf("\n"); } int main(int argc, char *argv[]) { list_node *list1 = list_init(); list_node *list2 = list_init(); list_insert(list1, 1); list_insert(list1, 4); list_insert(list1, 7); // list_insert(list1, 12); // list_insert(list1, 19); list_insert(list1, 61); list_insert(list2, 3); list_insert(list2, 9); list_insert(list2, 13); // list_insert(list2, 14); // list_insert(list2, 61); list_display(list1); list_display(list2); list_node *all = list_merger(list1, list2); list_display(all); return 0; }