首页 > C++的多个有序链表合并

C++的多个有序链表合并

已知k个已排序链表头节点指针,将这k个链表合并,合并后仍为有序的 ,返回合并后的头节点

如下三个链表:

在这里插入图片描述

合并后的结果如下:

在这里插入图片描述

方法一(STL sort算法进行排序):

  1. 先将输入的排序链表插入一个迭代器中,vector数组中国呢
  2. 直接对数组中的链表节点进行按值排序即可

实现算法如下,最终实现源码见文末:

bool cmp(Data *A, Data *B) { return A->data < B->data;
}
Data *merge_list2(vector<Data*> &list) { /*如果传入的链表数组大小为0,则返回空*/if(list.size() == 0) { return NULL;}/*传入的数组大小为1,则返回第一个链表头节点*/if(list.size() == 1) { return list[0];}/*遍历所有的链表,并将每个链表的所有节点插入一个vector中*/vector<Data*> result;for (int i = 0;i < list.size(); ++i) { while(list[i]) { result.push_back(list[i]);list[i] = list[i] -> next;}}/*对vector按照升序排序,其中排序规则可以由cmp函数自定义指定*/sort(result.begin(),result.end(),cmp);return result[0];
}

方法二(分治归并):

使用合并两个有序链表的实现,对所有链表进行两两合并至仅剩下两个,最后合并最后的两个链表,关于合并两个有序链表可以参考C语言的有序单链表合并

这里面的思想就是分而治之,将整体分割为一个个独立的个体分别处理,再进行最后的整合。

算法使用递归方式实现如下,最终实现源码见文末:

Data *merge_list(vector<Data *> &list) { /*如果传入的链表数组大小为0,则返回空*/if(list.size() == 0) { return NULL;}/*传入的数组大小为1,则返回第一个链表头节点*/if (list.size() == 1) { return list[0];}/*将链表分为两部分,分别放入不同的链表结构*/int mid = list.size() / 2;int i;vector <Data *> sub_list1,sub_list2;for (i = 0; i < mid; ++i) { sub_list1.push_back(list[i]);}for (i = mid; i < list.size(); ++i) { sub_list2.push_back(list[i]);}/*分别进行递归处理*/Data *list1 = merge_list(sub_list1);Data *list2 = merge_list(sub_list2);/*将以上两部分处理的最终结果返回,进行两个有序链表的合并*/return merge_two_list(list1,list2);
}

以上两个过程实现代码如下:

#include 
#include 
#include 
#include using namespace std;typedef struct LinkList { int data;struct LinkList *next;
}Data;
/*打印链表节点数值*/
void print_list(Data *head) { while (head) { printf("%d ",head->data);head = head -> next;}printf("
");
}
/*尾插法创建链表*/
Data *insert_tail(Data *head, int n) { head = (Data *)malloc(sizeof(Data));head->next = NULL;Data *r = head;while(n--) { Data *p = (Data *)malloc(sizeof(Data));int data;scanf("%d", &data);p->data = data;r->next = p;r = p;p->next = NULL;}return head->next;
}
/*合并两个有序链表算法实现*/
Data *merge_two_list(Data *headA, Data *headB) { Data p;p.data = 0;p.next = NULL;Data *result = &p;while (headA && headB) { if (headA->data < headB->data) { result->next = headA;headA = headA->next;} else { result->next = headB;headB = headB ->next;} result = result -> next;}if (headA == NULL) { result ->next = headB;}    if (headB == NULL) { result ->next = headA;}return p.next;
}
/*分治归并算法实现的链表合并*/
Data *merge_list(vector<Data *> &list) { if(list.size() == 0) { return NULL;}if (list.size() == 1) { return list[0];}int mid = list.size() / 2;int i;vector <Data *> sub_list1,sub_list2;for (i = 0; i < mid; ++i) { sub_list1.push_back(list[i]);}for (i = mid; i < list.size(); ++i) { sub_list2.push_back(list[i]);}Data *list1 = merge_list(sub_list1);Data *list2 = merge_list(sub_list2);return merge_two_list(list1,list2);
}
/*控制排序的规则,当前为升序*/
bool cmp(Data *A, Data *B) { return A->data < B->data;
}
/*排序算法实现链表的链表*/
Data *merge_list2(vector<Data*> &list) { if(list.size() == 0) { return NULL;}if(list.size() == 1) { return list[0];}vector<Data*> result;for (int i = 0;i < list.size(); ++i) { while(list[i]) { result.push_back(list[i]);list[i] = list[i] -> next;}}sort(result.begin(),result.end(),cmp);return result[0];
}int main() { vector<Data*> list;printf("input the num of the construct list 
");int num;scanf("%d",&num);for (int i = 0; i < num; ++i){ Data *p;printf("construct the %d list:
",i+1);list.push_back(insert_tail(p,3)); //尾插法构造三个节点的链表}printf("merget the mulity list with method 1 is 
");Data *result = merge_list(list);print_list(result);printf("merge the mulity list with method 2 is 
");Data *result2 = merge_list2(list);print_list(result2);return 0;
}

最终输出如下

input the num of the construct list 
4  
construct the 1 list:
1 2 3
construct the 2 list:
3 4 5
construct the 3 list:
4 5 6
construct the 4 list:
6 7 8
merget the mulity list with method 1 is 
1 2 3 3 4 4 5 5 6 6 7 8 
merget the mulity list with method 2 is 
1 2 3 3 4 4 5 5 6 6 7 8 

更多相关:

  • list_for_each_safeBidirect-list list_for_each_safe().https://biscuitos.github.io/blog/LIST_list_for_each_safe/...

  • /*hanzhiguang coded at 2009.07.30 1:20*/ // nesting_map.cpp : Defines the entry point for the console application. // /*-----------------------------------------------...

  • 本题要求实现一个函数,找到并返回链式表的第K个元素。 函数接口定义: ElementType FindKth( List L, int K ); 其中List结构定义如下: typedef struct LNode *PtrToLNode; struct LNode {ElementType Data;PtrToLNode Ne...

  • 一、前述 企业中linux搭建ftp服务器还是很实用的,所以本文针对centoos7和centoos6搭建服务器教程做个总结。 二、具体 1、显示如下图则表示已安装 vsftp软件。如果未显示则需要安装vsftpd软件。 如果没有则通过yarm源进行安装 yum install -y vsftpd 2、安装完成之后 进入到ftp的根...

  • 学习计划 MyPlan11 主题:Python描述统计、简单统计图形 时间:8.5-8.11周内完成 参考资料:新书《谁说菜鸟不会数据分析python篇》 各位星友们,在这个星球里每个人都要逼迫自己学习未知的领域或知识点,每天进步一点点,积累的时间久了 ,菜鸟也能起飞。 完成情况: 在pandas中,使用describe函数进行描述统...

  • 利用SocketServer模块来实现网络客户端与服务器并发连接非阻塞通信。 首先,先了解下SocketServer模块中可供使用的类: BaseServer:包含服务器的核心功能与混合(mix-in)类挂钩;这个类只用于派生,所以不会生成这个类的实例;可以考虑使用TCPServer和UDPServer。 TCPServer/UDPS...

  • 题目:序列化二叉树 请实现两个函数,分别用来序列化和反序列化二叉树。 示例:  你可以将以下二叉树:     1    /   2   3      /     4   5 序列化为 "[1,2,3,null,null,4,5]" 解题: /*** Definition for a binary tree no...

  • sd.js  import $global from "./global"; import $g from "./sg"; import $ from "jquery"; import {Message, Loading} from "element-ui";//引入饿了么相关组件 import {Base64} from "js-...

  •     原生sd.js----------------------------------------------------------------  const API_ROOT_URL = "http://www.api.com";const $d= {_postList_url: API_ROOT_URL + "/api...

  • 1.1 题目:反转链表:输入一个链表,反转链表后,输出新链表的表头。 1.2 思路:这道题,我们要做到的是反转链表,我们的思路是将前一个节点与后一个节点断开,然后让后一个节点指向前一个节点,这个过程就需要节点引用(可以理解为指针)来确定记录当前操作节点的前一个节点和后一个节点。 1.3 代码: 1 # -*- coding:utf...