题目:
Merge k sorted
linked lists and return it as one sorted list. Analyze and describe its complexity.
思路:
对于合并K个排好序的链表,最好的方法就是使用一个K个元素的最小堆,每次选择堆顶元素作为新的元素,等到K个元素均为空,说明所有的插入都已经结束。
不过这里也可以使用K个元素的数组来表示
#include <iostream>
#include <vector>
using namespace std;
/*
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
合并K个已经排好序的链表
这里的思想可以使用最小堆 每次使用堆顶元素来进行排序 但是也可以使用数组模拟
从数组中每次挑选最小的 然后组成元素
*/
typedef struct list_node List;
struct list_node
{
struct list_node* next;
int value;
};
void print_list(List* list)
{
List* tmp=list;
while(tmp != NULL)
{
cout<<tmp->value<<endl;
tmp = tmp->next;
}
}
/*
初始化List 将从1~n的数字插入到链表中
*/
void Init_List(List*& head,int* array,int n)
{
head = NULL;
List* tmp;
List* record;
/*
for(int i=1;i<=n;i++)
{
tmp = new List;
tmp->next = head;
tmp->value = i;
head = tmp;
}
*/
for(int i=1;i<=n;i++)
{
tmp = new List;
tmp->next = NULL;
tmp->value = array[i-1];
if(head == NULL)
{
head = tmp;
record = head;
}
else
{
record->next = tmp;
record = tmp;
}
}
}
int Len_list(List* list)
{
if(list == NULL)
return 0;
else
return Len_list(list->next)+1;
}
List* Merge_k(vector<List*>& vec)
{
int i;
vector<int> flag(vec.size(),1);
List* head=NULL;
List* cur=NULL;
List* tmp=NULL;
int pos;
while(1)
{
tmp = NULL;
for(i=0;i<vec.size();i++)
{
if(vec[i] == NULL)
flag[i] =0;
if(flag[i])
{
if(tmp == NULL)
{
tmp = vec[i];
pos = i;
}
if(tmp && tmp->value>vec[i]->value)
{
tmp = vec[i];
pos = i;
}
}
}
if(head == NULL)
{
head = tmp;
cur = head;
}
else
{
cur->next = tmp;
cur = cur->next;
}
vec[pos] = vec[pos]->next;
if(vec[pos]==NULL)
flag[pos] =0;
for(i=0;i<flag.size();i++)
{
if(flag[i])
break;
}
if(i >=flag.size())
{
break;
}
}
return head;
}
int main()
{
int array1[]= {1,4,7,8,13,19};
int array2[] = {5,8,9,10,12,15,17,22,23};
int array3[] = {3,6,11,16,17,18,21,24};
int array4[] = {2,14,20,25};
vector<List*> vec(4);
int i;
Init_List(vec[0],array1,sizeof(array1)/sizeof(array1[0]));
Init_List(vec[1],array2,sizeof(array2)/sizeof(array1[0]));
Init_List(vec[2],array3,sizeof(array3)/sizeof(array1[0]));
Init_List(vec[3],array4,sizeof(array4)/sizeof(array1[0]));
List* head = Merge_k(vec);
print_list(head);
return 0;
}
其实方便的方法是使用向量记录每个链表的节点,当某个链表为NULL,从这个向量中删除这个链表的记录,直到这个向量的大小为1就可以退出。而且合适的方法还是申请一个辅助节点。