算法(时间复杂度为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
原创粉丝点击