O(lgn)的三種排序,快速排序、歸併排序、堆排序

littleway發表於2014-05-15

快速排序:

取某個數作為中間數來進行比較,不斷的交換陣列中的兩個數,分成小於中間數和大於中間數的兩個分組,再對分組做快速排序(也就是用遞迴的思想)

歸併排序:

從中間把陣列分成兩部分,每部分都進行一次歸併排序(遞迴),然後再使用merge把這兩部分已排完序的陣列合併成順序陣列。

堆排序:

1、保持堆特性:左右兩子樹都為最大堆,只有父節點可能不滿足,於是遞迴的進行保持最大堆特性的運算(也就是不滿足就和子樹換,換完繼續對子樹進行保持對特性)

2、建堆:利用1中的函式,從葉子的父節點開始到根節點進行保持對特性的運算,從而達到建堆。

3、排序:由於建堆完成之後,根節點一定是最大值,因此不斷的把根節點和葉子交換,並且減少陣列大小。


程式碼附上:

void swap(int *vec, int i, int j)
{
	int tmp = vec[i];
	vec[i] = vec[j];
	vec[j] = tmp;
}

void quicksort(int *vec, int beg, int end)
{
	if(beg < end)
	{
		//每次都取最後一位數當比較數;
		int num = vec[end];
		int mid = beg;

		for(int i = beg; i < end; ++i)
		{
			if(vec[i] < num)
			{
				swap(vec, i, mid++);
			}
		}
		swap(vec, mid, end);
		quicksort(vec, beg, mid - 1);
		quicksort(vec, mid+1, end);
	}
}


void merge(int *vec, int p, int q, int end)
{
	int n1 = q-p;
	int n2 = end - q + 1;

	int *l = new int[n1];
	int *r = new int[n2];
	for(int i = 0; i < n1; ++i)
	{
		l[i] = vec[p + i];
	}
	for(int i = 0; i < n2; ++i)
	{
		r[i] = vec[q + i];
	}
	int l_beg = 0;
	int r_beg = 0;
	for(int i = p; i <= end; ++i)
	{
		if(l_beg == n1)
		{
			while(r_beg != n2)
				vec[i++] = r[r_beg++];
			break;
		}
		else if(r_beg == n2)
		{
			while(l_beg != n1)
				vec[i++] = l[l_beg++];
			break;
		}

		if(l[l_beg] < r[r_beg])
			vec[i] = l[l_beg++];
		else
			vec[i] = r[r_beg++];
	}
}
void mergesort(int *vec,int beg, int end)
{
	if(beg < end)
	{
		int q = (beg+end)/2;
		mergesort(vec, beg, q);
		mergesort(vec, q+1, end);

		merge(vec, beg, q+1, end);
	}

}

//root = 0;
//parent(i) = (i+1)/2-1;
//left(i) = 2*i+1;
//right(i) = 2*(i+1);
void maxHeap(int vec[],int n, int index)
{
	if(index * 2 + 2 <= n)
	{
		int p = vec[index];
		int l = vec[index*2 + 1];
		int r = vec[index*2 + 2];
		int maxIndex = p >= l ? index : index*2 + 1;
		maxIndex = vec[maxIndex] >= r ? maxIndex : index*2 + 2;

		if(maxIndex != index)
		{
			swap(vec, index, maxIndex);
			maxHeap(vec, n, maxIndex);
		}
	}
	else if(index * 2 + 1 == n)
	{
		int p = vec[index];
		int l = vec[index*2 + 1];
		if(l > p)
		{
			swap(vec, index, index*2);
		}
	}	
}
void buildHeap(int vec[], int n)
{
	int beg = (n+1)/2 - 1;
	for(int i = beg; i >= 0; --i)
	{
		maxHeap(vec, n, i);
	}
}
void heapsort(int vec[], int n)
{
	buildHeap(vec, n);
	for(int i = n; i > 0; --i)
	{
		swap(vec, 0, i);
		maxHeap(vec, i-1, 0);
	}
}


相關文章