问题:
把k个有序表合并成一个有序表。k个有序表总共有n个元素。
解决思路(书上的):
把每个表的的当前元素放入优先级队列中,每次从优先级队列中删除最小值并放入到新表中,然后加入入此序列的下一个元素。
时间复杂度分析:每次操作需要logk时间,因此总共需要nlogk的时间。
实现代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
using std::cout ;
using std::endl ;
#define K 50 //K路合并的最大K
/*--------------------------------------------------------------------------
优先级队列的实现
--------------------------------------------------------------------------*/
#define INIFINE -10000
#define LEFT(i) (2*(i))
#define RIGHT(i) (2*(i)+1)
#define PARENT(i) ((i)/2)
class PriorityQueue
{
public:
PriorityQueue() ;
PriorityQueue( int *pFirst, int *pLast ) ;
~PriorityQueue() ;
public:
void BuildMinHeap() ;
void MinHeapInsert(int nKey) ;
int HeapMinimun() ;
int HeapExtractMin() ;
void DebugPrint() ;
private:
void MinHeapify( int i ) ;
void HeapDecreaseKey(int i,int nKey) ;
private:
enum QUE_SIZE { MAX = 1000 } ; //The heap max size
private :
int m_nHeapSize ;
int m_nLength ;
int m_C[MAX];
} ;
void PriorityQueue::DebugPrint()
{
for(int i = 1 ; i <= m_nHeapSize ; ++i)
{
cout << m_C[i] << ' ' ;
}
cout << endl ;
}
PriorityQueue::~PriorityQueue()
{
m_nHeapSize = 0 ;
m_nLength = 0 ;
}
PriorityQueue::PriorityQueue( int *pFirst, int *pLast )
{
int i = 1 ;
m_nHeapSize = m_nLength = 0 ;
while(pFirst != pLast)
{
m_C[i] = *pFirst ;
pFirst++ ;
m_nLength++ ;
i++ ;
}
m_nHeapSize = m_nLength ;
BuildMinHeap() ;
}
PriorityQueue::PriorityQueue():
m_nHeapSize(0) ,m_nLength(0)
{
}
int PriorityQueue::HeapExtractMin()
{
int nMin = 0 ;
if(m_nHeapSize < 1)
{
return -1 ;
}
nMin = m_C[1] ;
m_C[1] = m_C[m_nHeapSize] ;
m_nHeapSize-- ;
m_nLength-- ;
MinHeapify(1) ;
return nMin ;
}
int PriorityQueue::HeapMinimun( )
{
return m_C[1] ;
}
void PriorityQueue::BuildMinHeap()
{
int i ;
m_nHeapSize = m_nLength ;
for(i = m_nLength/2 ; i >= 1 ; --i)
{
MinHeapify(i) ;
}
}
void PriorityQueue::MinHeapify( int i )
{
int l,r,nTemp,nMininum ;
l = LEFT(i) ;
r = RIGHT(i) ;
if(l <= m_nHeapSize && m_C[i] > m_C[l])
{
nMininum = l ;
}
else
{
nMininum = i ;
}
if(r <= m_nHeapSize && m_C[nMininum] > m_C[r] )
{
nMininum = r ;
}
if(i != nMininum )
{
nTemp = m_C[i] ;
m_C[i] = m_C[nMininum] ;
m_C[nMininum] = nTemp ;
MinHeapify(nMininum) ;
}
}
void PriorityQueue::MinHeapInsert(int nKey)
{
m_nHeapSize++ ;
m_nLength++ ;
m_C[m_nHeapSize] = -INIFINE ; //aim to keep the heap attribute
HeapDecreaseKey( m_nHeapSize,nKey ) ;
}
void PriorityQueue::HeapDecreaseKey(int i,int nKey)
{
int nTemp = 0 ;
if(nKey > m_C[i])
{
return ;
}
m_C[i] = nKey ;
while(i > 1 && m_C[PARENT(i)] > m_C[i])
{
nTemp = m_C[i] ;
m_C[i] = m_C[PARENT(i)] ;
m_C[PARENT(i)] = nTemp ;
i = PARENT(i) ;
}
}
/*--------------------------------------------------------------------------
优先级队列的实现
--------------------------------------------------------------------------*/
typedef struct ListNode
{
int m_Data ;
ListNode *m_pNext ;
} ListNode ;
int FindNextNodeToHeap( ListNode* A[] ,int k ,int nKey ) ;
void PrintResult(int C[], int nLen ) ;
void PrintResult(int C[],int nLen)
{
for(int i = 0 ; i < nLen ; ++i )
{
cout << C[i] << ' ' ;
}
cout << endl ;
}
int FindNextNodeToHeap( ListNode* A[] ,int k ,int nKey)
{
int i = 0 ;
for(i = 0 ; i < k ; ++i)
{
if(A[i]->m_pNext != NULL && A[i]->m_pNext->m_Data == nKey )
{
return i ;
}
}
return -1 ;
}
int main(void)
{
int i,j,k,n,nTotalSize ; //k为有多少路序列,
ListNode* A[K] ;
freopen("in.txt","r",stdin) ; //测试文件
while(scanf("%d",&k) != EOF )
{
nTotalSize = 0 ;
for(i = 0 ; i < k ; ++i)
{
ListNode *pNode = new ListNode ;
pNode->m_pNext = NULL ;
pNode->m_Data = 0 ;
A[i] = pNode ;
ListNode *pCurNode = pNode ;
scanf("%d",&n) ;
for(j = 0 ; j < n ; ++j)
{
ListNode *pNode = new ListNode ;
pNode->m_pNext = NULL ;
scanf("%d",&(pNode->m_Data)) ;
pCurNode->m_pNext = pNode ;
pCurNode = pNode ;
nTotalSize++ ;
}
}
PriorityQueue queue ;
int *pC = new int[nTotalSize] ;
int nNextNodeToHeap = -1 ;
int l = 0 ;
for(i = 0 ; i < k ; ++i)
{
queue.MinHeapInsert( A[i]->m_pNext->m_Data ) ;
}
while( nTotalSize-- > 0 )
{
pC[l] = queue.HeapExtractMin() ;
nNextNodeToHeap = FindNextNodeToHeap( A,k,pC[l]) ;
ListNode *pToDelNode = A[nNextNodeToHeap]->m_pNext ;
A[nNextNodeToHeap]->m_pNext = A[nNextNodeToHeap]->m_pNext->m_pNext ;
delete pToDelNode ;
if( A[nNextNodeToHeap]->m_pNext != NULL)
{
queue.MinHeapInsert( A[nNextNodeToHeap]->m_pNext->m_Data ) ;
}
l++ ;
}
PrintResult(pC,l) ;
delete [] pC ;
}
return 0 ;
}
/*
测试用例:
Input Sample
5 //有多少路,5路
3 //第一路有多少个元素
4 5 8 //第一路的输入元素
5 //第二路有多少个元素
1 3 7 9 10 //第二路的输入元素
2 //第三路有多少个元素
2 4 //第三路的输入元素
4 //第四路有多少个元素
5 6 7 //第四路的输入元素
1 //第五路有多少个元素
1 //第五路的输入元素
Output Sample
1 1 2 3 4 4 5 5 6 7 7 8 9 10 11
*/
题外话:
好久没写博客了,当然,偷懒是主要原因啦~~
另外工作也落实了,很开心,大学的努力有回报了~~
不过,这也只是一个新的起点而已,日子还是得继续~~