數據結構之排序算法之O(n^2)

在數據結構中講解了7中排序算法,冒泡、選擇、插入、希爾、堆排序、歸併、快速排序。希爾排序感覺有點神,還沒搞明白,以後再說。

本篇講述冒泡、選擇、插入這3種時間複雜度O(n^2)的算法

冒泡排序

冒泡排序非常簡單,但是如果正常寫的話還是有優化的餘地的,一般我們寫的代碼爲:

void BubbleSort_1(double *a,int low,int high)
{
	if (!a||high<low)
		return;

	int i,j;
	for (i=low;i<=high-1;i++)
	{
		for (j=i+1;j<=high;j++)
		{
			if (a[i]>a[j])
			swap(&a[i],&a[j]);
		}
	}
}



但是這種方法後面部分(i後面的數組)的數值順序是不變的,如果按照正宗的“冒泡”來的話,每一次 i 循環後,較小的數都會相應的向前靠攏,代碼修改爲:

void BubbleSort_2(double *a,int low,int high)
{
	if (!a||high<low)
		return;

	int i,j;
	for (i=low;i<=high-1;i++)
	{
		for (j=high-1;j>=i;j--)
		{
			if (a[j]>a[j+1])
				swap(&a[j],&a[j+1]);
		}
	}
}



還有一種,如果某次循環後數組後面已經是順序的話,那就不需要在進行排序了,加入一個標誌位即可:

void BubbleSort_3(double *a,int low,int high)
{
	if (!a||high<low)
		return;

	int i,j;
	bool sign=true;
	for (i=low ; i<=high-1&&sign ; i++)
	{
		sign=false;
		for (j=j=high-1 ; j>=i ; j--)
		{
			if (a[j]>a[j+1])
			{
				swap(&a[j],&a[j+1]);
				sign=true;
			}
		}
	}
}


選擇排序

這個就比較簡單了,從首位開始,每次都選擇當前位和後面數組中最小的來交換當前位。

void SelectSort(double* a,int low,int high)
{
	if (!a||high<low)
		return;

	int i,j,min;
	for (i=low;i<=high;i++)
	{
		min=i;
		for (j=i+1;j<=high;j++)
		{
			if (a[j]<a[min])
				min=j;
		}
		swap(&a[i],&a[min]);
	}
}

插入排序

插入排序的算法也很簡單,就是假設當前位之前的數組已經排序好,然後把當前位插入到前面數組的合適位置,具體做法爲依次比較,直到找到比當前位小的值。

void InsertSort(double* a,int low,int high)
{
	if (!a||high<low)
		return;

	int i,j;
	double key;

	for (i=low ; i<high ; i++)
	{
		j=i;
		key=a[i+1];
		while (a[j]>key&&j>=low)
		{
			a[j+1]=a[j];
			j--;
		}
		a[j+1]=key;
	}
}


可以粗略估計下這3個排序的優劣,冒泡和選擇排序的比較次數都是相同的,都是O(n^2),但是選擇排序的交換操作比冒泡少,所以選擇要比冒泡強。而插入排序在最壞情況下的比較次數和選擇排序是一樣的,但是如果數組已經基本有序的話,那麼內循環的執行次數是比較少的,

所以平均情況下,插入排序 優於 選擇排序 優於 冒泡排序

現在我們來測試下這3種方法的時間,測試數組大小爲5萬,裏面的值是隨機生成的浮點值。(結果冒泡中第一種時間最短,好糾結啊)



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章