以下三种插入排序时间复杂度均为O(n^2)

简单插入排序,简单直接。假定数组有序,插入 i, 从后往前遍历找到适合位置 j,移动 j +1 ~ i -1往后一位,插入i到j中。

void insertSort(int *arr, int numsSize)
{
	int i, j, k, v;
	for (i = 1; i < numsSize; i++)
	{
		for (j = i - 1; j >= 0; j--)
		{
			if (arr[i] >= arr[j])
				break;
		}
		v = arr[i];
		
		for (k = i; k > j + 1; k--)
			arr[k] = arr[k-1];
		arr[k] = v;	
	}
	return;
}

折半插入排序,和简单插入排序相比减少比较次数,稍稍好那么一丢丢,时间复杂度还是O(n^2)

void BiInsertSort(int *arr, int numsSize)
{
	int high, low, m, i, j, v;
	for (i = 1; i < numsSize; i++)
	{
		high = i - 1;
		low = 0;
		v = arr[i];
		while (low <= high)
		{
			m = (low + high)/2;
			if (arr[m] >= arr[i])
				high = m - 1;
			else
				low = m + 1;
		}
		for (j = i; j > low; j--)
		{
			arr[j] = arr[j-1];
		}
		arr[low] = v;
	}
}

2路插入排序,减少移动次数,额外增加一个循环数组,需要考虑边界溢出,特别容易出错。时间复杂度和其它插入排序相比没有基本改变,不建议使用但是要理解并能够写出代码。first和final分别表示循环数组中的起始位置。

void insertSort2(int *array, int arraysize)
{
	int final, first, i, j, n;
	final = first = 0;

	if (!array || arraysize < 1)
		return ;
		
	int *tmp = (int *)malloc(sizeof(int) * arraysize);
	if (!tmp)
	{
		printf("malloc error\n");
		return ;
	}

	tmp[0] = array[0];
	for (i = 1; i < arraysize; i++)
	{
		if (array[i] >= tmp[0])
		{
			//插入到左边
			j = final;
			while(array[i] < tmp[j])j--;
			
			for (n = ++final; n > j + 1; n--)
				tmp[n] = tmp[n-1];
			tmp[n] = array[i];	
		}
		else
		{
			//插入到右边
			if (first == 0)
			{
				first = arraysize - 1;
				tmp[first%arraysize] = array[i];
			}			
			else
			{
				j = first - arraysize;
				while(tmp[(j + arraysize)%arraysize] < array[i])
					j++;
				for (n = (--first - arraysize); n < (j - 1); n++)
					tmp[(n + arraysize)%arraysize] = tmp[(n + 1 + arraysize)%arraysize];
					
				tmp[(n + arraysize)% arraysize] = array[i]; 
			}
		}
	}
}

=============================================================================================

Linux应用程序、内核、驱动、后台开发交流讨论群(745510310),感兴趣的同学可以加群讨论、交流、资料查找等,前进的道路上,你不是一个人奥^_^。