算法(时间复杂度为O(nlgk)的k有序链(从小到大)表合并为一个有序链表
来源:互联网 发布:网络侵权责任纠纷 编辑:程序博客网 时间:2024/06/01 09:51
问题描述:
设计时间复杂度为O(nlgk)的算法,它能够将k个有序链表合并为一个有序链表,这里的n是所有输入链表包含的总元素个数。
问题分析:
采用最小堆的方法求解。1.取k个链表的第一个元素,构成一个最小堆。
2.取掉最小堆的根及数组下标为零的元素放入大小为n的数组中,再在所取根元素所在的链表中去下一个元素放入堆的根位置,如果链表有一个为空,则堆大小减一,然后维持最小堆。
3.重复步骤2,直到所有链为空。
#include "stdafx.h"#include<iostream>using namespace std;struct LNode{int a;LNode *next;};LNode *pr;//记录链表中下标为x的元素位置(设为全局变量)int Size(LNode * p)//链表长度{int i=0;while(p&&p->next){i++;p=p->next;}return i;}LNode*&Locate(LNode *p,int x)//返回链表中指向x位置的元素{pr=p->next;while(pr&&x>0){pr=pr->next;x--;}return pr;}void CreateLNode(LNode* &L,int n)//创建链表{L=new LNode();L->next=NULL;for(int i=0;i<n;i++){LNode *p=new LNode();cin>>p->a;p->next=L->next;L->next=p;}}void Create_Empty_LNode(LNode* &L,int n)//创建空链表{L=new LNode();L->next=NULL;for(int i=0;i<n;i++){LNode *p=new LNode();p->a=0;p->next=L->next;L->next=p;}}LNode *& Locat_LNode(LNode *p[],int a,int n)//确定堆根元素属于哪个链{ int i=0;while(i<n){LNode *pr=p[i];while(pr&&pr->next){pr=pr->next;if(a==pr->a){p[i]=pr;return p[i];}}i++; }}void Keep_Min_Heapify(LNode * &a,int i,int n)//维持最小堆{int l=2*i;int r=2*i+1;int large=0;if(l<Size(a)&&Locate(a,l)->a<Locate(a,i)->a){large=l;}else{large=i;}if(r<Size(a)&&Locate(a,r)->a<Locate(a,i)->a){large=r;}if(large!=i){int temp=0;temp=Locate(a,i)->a;Locate(a,i)->a=Locate(a,large)->a;Locate(a,large)->a=temp;Keep_Min_Heapify(a,large,n);}return ;}void Create_Min_Heapify(LNode *&a,int n)//创建最小堆{for(int i=n/2;i>=0;i--){Keep_Min_Heapify(a,i,n);}return ;}int _tmain(int argc, _TCHAR* argv[]){const int K=3;LNode *p[K];int n1;cout<<"请输入第一个链表长度\n";cin>>n1;CreateLNode(p[0],n1);//有序输入,且为倒序构建链表.int n2;cout<<"请输入第二个链表长度\n";cin>>n2;CreateLNode(p[1],n2);//有序输入,且为倒序构建链表.int n3;cout<<"请输入第二个链表长度\n";cin>>n3;CreateLNode(p[2],n3);//有序输入,且为倒序构建链表.int *A =new int [n1+n2+n3];//存放合并后的链表int Alable=0;//标示A的下标LNode * a=0;//最小堆Create_Empty_LNode(a,K);LNode * ar=a->next;for(int i=0;i<K;i++){LNode *pr=p[i];pr=pr->next;ar->a=pr->a;ar=ar->next;}//取链表的第一个元素存入a中Create_Min_Heapify(a,K-1);//创建最小堆int k=K;//记录链表个数while(k>=1){LNode *L=0;A[Alable++]=a->next->a; L=Locat_LNode(p,a->next->a,K);if(L->next==NULL){LNode *a1=a;while(a1->next){ a1=a1->next;}a->next->a=a1->a;k--; Keep_Min_Heapify(a,0,k);}else{a->next->a=L->next->a;if(k!=1){ Keep_Min_Heapify(a,0,k);}}}//2,3步程序实现for(int i=0;i<n1+n2+n3;i++){ cout<<A[i]<<endl;}return 0;}
注意:链表的创建为倒序创建 链表有序(从小到大)输入要从大到小 eg:链表 3,6,9 输入要是9,6,3.
0 0
- 算法(时间复杂度为O(nlgk)的k有序链(从小到大)表合并为一个有序链表
- K个有序链表共N个结点在O(NlgK)时间合并为一个新的有序链表实现文件C语言
- K个有序链表共N个结点在O(NlgK)时间合并为一个新的有序链表头文件C语言
- 合并两个有序链表--实现1+2+3+....+n,时间复杂度为O(1)
- 两个有序链表合并为有序
- 两个有序链表合并为一个有序链表
- 两个有序链表合并为一个有序链表
- 两个有序链表求差集,合并为一个有序链表
- 9、单链表的合并,两个有序单链表,合并为一个有序链表。
- 合并两个有序的链表为有序链表
- C语言实现合并两个有序(从小到大)顺序表为一个顺序表
- 将两个递增的有序链表合并为一个递增的有序链表
- 合并两个有序的链表为一个有序的链表
- 把两个有序链表合并为一个有序链表(注意空指针异常!)
- 将两个递增的有序链表合并为一个递增的有序链表(C语言编程实现)
- 两个有序链表合并为一个链表
- 两个递增有序链表合并为一个链表
- 分段有序数组合并成有序(空间复杂度为O(1))
- 编程之美—字符串移位包含问题
- Reflector反编译软件激活和使用
- uva 10285 Longest Run on a Snowboard
- 数据挖掘考试重点(条理版)
- override作为c++保留字的用发
- 算法(时间复杂度为O(nlgk)的k有序链(从小到大)表合并为一个有序链表
- poj1141
- Easyui开发部门管理模块_部分模块code.jsp
- CareerCup chapter 3 Stacks and Queues
- POJ2368 Buttons
- 【翻译】Ext JS 4——Ajax和Rest代理处理服务器端一场和消息的方法
- [notes] ImageNet Classification with Deep Convolutional Neual Network
- WM_NCHITTEST消息
- Nmap Cheat Sheet: From Discovery to Exploits – Part 1: Introduction to Nmap