1. 程式人生 > >將兩個已排序的連結串列歸併成一個連結串列(C++面試題)

將兩個已排序的連結串列歸併成一個連結串列(C++面試題)

題目:

將兩個已經排好序的連結串列組合成一個排序的連結串列。

/*
	歸併排序的思想
	時間:2015年4月8日 19:59:02
*/

#include <iostream>
#include <cstdlib>
using namespace std;

typedef struct Node	//模擬節點
{
	int data;
	struct Node * next;
}NODE,* PNODE;

class List
{
private:
	PNODE pHead;	
	int len;	//連結串列長度
public:
	List(int _len=0);	//初始化連結串列
	List(List & blist); //拷貝建構函式
	~List();	
	void create()const;	//隨機建立一個連結串列
	void traverse1()const;	//遍歷
	void bubble_sort();	//氣泡排序
	PNODE Merge(List & blist)const;	//歸併排序
	int show(){return len;}		//返回長度
};

void traverse2(PNODE pHead);

int main()
{
	int len1,len2;
	cout<<"請輸入一個大於0的數作為第一個連結串列的長度: ";
	cin>>len1;
	cout<<"請輸入一個大於0的數作為第二個連結串列的長度: ";
	cin>>len2;

	List A(len1); //長度為len1的連結串列
	A.create();	//建立A物件連結串列
	cout<<"連結串列A有"<<A.show()<<"個元素"<<",未排序時:"<<endl;
	A.traverse1();
	cout<<"連結串列A排序後:"<<endl;
	A.bubble_sort(); //排序
	A.traverse1();
	cout<<endl<<endl;

	List B(len2); //長度為len1的連結串列
	B.create();		//建立B物件連結串列
	cout<<"連結串列B有"<<B.show()<<"個元素"<<",未排序時:"<<endl;
	B.traverse1();
	cout<<"連結串列B排序後:"<<endl;
	B.bubble_sort();	//排序
	B.traverse1();
	cout<<endl<<endl;

	cout<<"歸併後的連結串列為:"<<endl;
	PNODE p =A.Merge(B);
	traverse2(p);
	cout<<endl<<endl;

	return 0;
}

List::List(int _len )	//預設連結串列長度為0
{
	pHead = new NODE;
	pHead->next = NULL;
	len = _len;
}

List::List(List & blist)  //拷貝建構函式
{
	pHead = new NODE;
	PNODE pTail = pHead;
	pTail->next = NULL;
	len = blist.len;

	for(int i=0; i<len; i++)
	{
		PNODE pNew = new NODE;
		pNew->data = blist.pHead->data;
		pTail->next = pNew;
		pNew->next = NULL;
		pTail = pNew;
		blist.pHead = blist.pHead->next;
	}
}

List::~List()	//刪除連結串列
{
	NODE * temp = NULL;
	while(pHead != NULL)
	{
		temp = pHead->next;
		delete pHead;
		pHead = temp;
	}
}

void List::create()const	//建立長度為len的連結串列
{
	if(len <= 0)
		return;
	int i;
	PNODE pTail = new NODE;
	pTail->next = NULL;
	pTail = pHead;

	for(i=0; i<len; i++)
	{
		PNODE pNew = new NODE;
		pNew->data = rand()%1000; //1000以內的隨機非負數
		pTail->next = pNew;
		pNew->next = NULL;
		pTail = pNew;
	}
	return;
}

void List::traverse1()const	//遍歷
{

	PNODE temp = pHead->next;
	while(temp != NULL)
	{
		cout<<temp->data<<" ";
		temp = temp->next;
	}
	cout<<endl;
	
	return;
}

void List::bubble_sort()
{
	if(len <= 1) //長度小於等於1,則不用排序
		return;

	int temp;
	PNODE pTemp = pHead->next;
	PNODE pNew =pTemp;
	for(int i=0; i<len-1; i++)
	{
		for(int j=0; j<len-i-1; j++ )
		{
			if( pNew->next && pNew->data > pNew->next->data )
			{
				temp = pNew->data;
				pNew->data = pNew->next->data;
				pNew->next->data = temp;
			}
			pNew = pNew->next;
		}
		pNew = pTemp;
	}
	return ;
}

PNODE List::Merge(List & blist) const	//歸併
{
	int m=0, n=0;//m計數本物件,n計數形參物件
	PNODE m_temp = pHead->next;
	PNODE n_temp = blist.pHead->next;

	PNODE p = new NODE;
	PNODE pTail = p;
	pTail->next = NULL;
	while(m<len && n<blist.len)  //當有一個連結串列比較完了,另外一個連結串列只要接上去就OK
	{
		if(m_temp->data < n_temp->data)
		{
			PNODE pNew = new NODE;
			pNew->data = m_temp->data;
			pTail->next = pNew;
			pNew->next = NULL;
			pTail = pNew;
			m_temp = m_temp->next;
			m++;
		}
		else if(m_temp->data > n_temp->data)
		{
			
			PNODE pNew = new NODE;
			pNew->data = n_temp->data;
			pTail->next = pNew;
			pNew->next = NULL;
			pTail = pNew;
			n_temp = n_temp->next;
			n++;
		}
	}
	
	//看哪個連結串列還有沒比較完的元素
	if( m<len ) 
	{
		pTail->next = m_temp;
	}
	else if(n<blist.len)
	{
		pTail->next = n_temp;
	}

	return p;
}

void traverse2(PNODE pHead) //這個不是類裡的遍歷函式
{
	PNODE temp = pHead->next;
	while(temp != NULL)
	{
		cout<<temp->data<<" ";
		temp = temp->next;
	}
	cout<<endl;
	
	return;
}