1. 程式人生 > >【演算法】氣泡排序(從小到大) 排序範圍(0~n-1)n為陣列元素個數

【演算法】氣泡排序(從小到大) 排序範圍(0~n-1)n為陣列元素個數

  今天要談的是基本排序演算法中的氣泡排序。除了氣泡排序,基本排序演算法還包括:選擇排序插入排序

  插入排序演算法的思想也是很簡單的,它把排序過程模擬成了從水底冒氣泡的過程一趟排序過程結束後,最小(最輕)的元素就已經“浮”到水面上了。接下來就是不斷縮小排序範圍,把每個排序範圍中最小的元素交換到陣列頭

  接下來就來分析演算法,我們使用的資料是1 3 2 8 0 6 共6個元素

  

  我們總的排序範圍為0~5,即0~n-1,我們令一個指標j指向陣列的最後一個元素,至於j有啥“特異功能”,慢慢往後看~

  

1、第一趟,排序範圍(0,5),目標是將其中的最小值0,交換至陣列頭。將a[j]與a[j-1]的值相比較,如果a[j-1] > a[j]則將a[j]的值與a[j-1]的值進行交換,要把小的值往前推嘛~

   

  顯然j指標就是為了在不斷比較當中尋找待排序陣列中的最小值,並把它存於陣列頭。

2、第二趟,排序範圍(1,5),目標是將其中的最小值1,交換至陣列頭。

   

3、第三趟,排序範圍(2,5),目標是將其中的最小值2,交換之陣列頭。


4、第四趟,排序範圍(3,5),目標是將其中的最小值3,交換至陣列頭


5、第五趟,排序範圍(4,5),目標是將其中的最小值6,交換至陣列頭


至此,排序結束,最終序列為


我們通過觀察,發現我們總共6個元素,排序進行了5趟;每趟排序開始前,j指標總指向末尾;交換資料的條件為a[j-1] >a[j];a[j]總指向當前遍歷過的最小的值

不想太多,直接根據我們的結論寫程式碼。我們可以分成兩個部分

實現:

void pop(Elemtype a[] , int begin , int end)
{
	int j;
	for(j = end ; j > begin ; j--)
	{
		//將最小值往前推
		if(a[j-1] > a[j])
		{
			swap(&a[j-1],&a[j]);
		}
	}
}

void sort(Elemtype a[] , int begin , int end)
{
	int i;
	//執行n-1次
	for(i = begin ; i < end ; i++)
	{
		pop(a,i,end);
	}
}

void swap(Elemtype *a , Elemtype *b)
{
	Elemtype t = *a;
	*a = *b;
	*b = t;
}

完整程式如下:
#include <stdio.h>
#define Elemtype int
void swap(Elemtype *a , Elemtype *b);

void pop(Elemtype a[] , int begin , int end)
{
	int j;
	for(j = end ; j > begin ; j--)
	{
		//將最小值往前推
		if(a[j-1] > a[j])
		{
			swap(&a[j-1],&a[j]);
		}
	}
}

void sort(Elemtype a[] , int begin , int end)
{
	int i;
	//執行n-1次
	for(i = begin ; i < end ; i++)
	{
		pop(a,i,end);
	}
}

void swap(Elemtype *a , Elemtype *b)
{
	Elemtype t = *a;
	*a = *b;
	*b = t;
}

void display(Elemtype a[] , int begin , int end)
{
	int i;
	for(i = begin ; i <= end ; i++)
	{
		printf("%d ",a[i]);
	}
	printf("\n");
}

int main()
{
	Elemtype a[] = {1,3,2,8,0,6};
	sort(a,0,5);
	display(a,0,5);
	return 0;
}

程式執行效果如下:


氣泡排序的時間複雜度為O(n^2)

PS.不要胡思亂想不要胡思亂想,跟著分析走就好,不然會繞進死衚衕。。。