1. 程式人生 > >【排序演算法2】插入排序

【排序演算法2】插入排序

插入排序的中心思想就是將一個元素插入到已經排好序的陣列當中。
陣列a[n]
初始時,a[0]自成一格有序區,無序區為a[1…n-1] 令i = 1
將a[i]併入當前有序區a[0…i-1]中形成有序區間
i++並重復第二步直到 i == n -1

#include <stdio.h>
#include <Windows.h>
#include "MyFunctions.h"
/*
	陣列a[n]
		1.初始時,a[0]自成一格有序區,無序區為a[1....n-1]  令i = 1
		將a[i]併入當前有序區a[0...i-1]中形成有序區間
		i++並重復第二步直到 i == n -1
*/



void insert_sort(int a[],int n)
{
	int i,j,k,temp;
	for( i = 1; i < n ; ++i )
	{
		for( j = i - 1 ; j >= 0 ; --j )
		{
			/*
			if( a[i] < a[j - 1] )
			{
				a[j] = a[j - 1];  //這裡不能交換資料,因為a[i]的資料可能會被前面的資料覆蓋
			}
			else
			{
				//a[j] = temp;
				break;
			}
			*/

			if( a[j] < a[i]  )
			{
				break;
			}
		}
		//判斷j的位置是否是原來的位置,不是的話要將資料後移至j之後
		if( j != i - 1 )
		{
			temp = a[i];
			for( k = i - 1 ; k > j ; --k )
			{
				a[k + 1] = a[k];
			}
			a[k + 1] = temp;
		}
		//a[j] = temp;  上面 j == i的情況下a[j]會被賦值成上次的temp
		// j == i 就不用換
	}
}

//優化上面的插入排序
void insert_sort2(int a[],int n)
{
	int i,j,temp;
	for(int i = 1; i < n ; ++i )
	{
		if( a[i] < a[i - 1] )
		{
			temp = a[i];
			for(j = i - 1 ; j >= 0 && a[j] > temp ; --j)  //退出的情況j < 0 || a[j] <= temp所以不管哪種退出情況這個插入的位置都是j+1
			{
				a[j + 1] = a[j];
			}
			a[j + 1] = temp;
		}
	}
}

//優化insert_sort2,不用前一個數據覆蓋後一個數據的方法,而是使用2個數據交換的方式
void insert_sort3(int a[],int n)
{
	for(int i = 1 ; i < n ; ++i )
	{
		if( a[i] < a[i - 1] )
		{
			//for( int j = i - 1 ; j >= 0 ; --j )
			//{
			//	if( a[j + 1] < a[j] )
			//	{
			//		Swap(&a[j + 1],&a[j]);  //如果前一個數比後一個數大就交換
			//	}
			//	else
			//	{
			//		break;  //如果沒有交換就代表著這次插入排序已經完成
			//	}
			//}
			
			//優秀寫法  與上面的邏輯一模一樣
			for( int j = i - 1 ; j >= 0 && a[j + 1] < a[j] ; --j)
			{
				PJDSwap(&a[j + 1],&a[j]);
			}

		}
	}
}



int main()
{
	int a[10] = {5,3,7,0,9,4,1,8,2,6};
	insert_sort3(a,10);
	PJDprint(a,10);
	system("pause");
	return 0;
}

這裡偷了個小小的懶,我將Swap函式和Print函式放到了自己寫的函式檔案中,這樣就不用每次都寫一遍,嘿嘿。
我以前不是很瞭解,一直以為插入排序要開闢一個與原陣列一樣大的空間,向其中插入資料。
這裡非常感謝MoreWindows的系列部落格白話經典演算法白話經典演算法