【申明:本文仅限于自我归纳总结和相互交流。有纰漏还望各位指出。 联系邮箱:Mr_chenping@163.com】
题目:
两个有序单链表合并为一个有序的单链表(默认升序)
题目分析:
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(" "); } 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; }