没事儿就学习(3):插入排序

直接插入排序

      直接插入排序是一种最简单的排序方法,其基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的有序表。其插入流程可以非常简单的进行表示。

       在已有的{3,4,9}有序表中插入8,首先和3进行比对,发现8>3不符合插入条件向后移,然后和4进行比对,发现8>4不符合插入条件向后移,直到遇见9。8需要插入在9的前面,因此在线性表中需要将9及其后的数字向后移一个位置,然后将8插入在该位置上。

       将上述的概念转移至已有的无序序列进行排序,则从序列的第二个数值开始遍历该无序序列,将当前指向的数值插入到该数值前的序列中即可。

//@list 需排序数组
//@count 数组长度
//直接插入排序
void StraightInsertionSort(int *list, int count) {
	for (int i = 1; i < count; i++) {
		int insertNum = list[i];
		for (int j = 0; j < i; j++) {
			int compareNum = list[j];
			if (insertNum < compareNum) {
				for (int k = i; k > j; k--) {
					list[k] = list[k - 1];
				}
				list[j] = insertNum;
				break;
			}
		}
	}
}

折半插入排序

      折半插入排序是一种改进的插入排序算法,由于直接插入排序存在从左到右依次搜索导致的搜索次数较多,效率较低的问题。结合数学中二分法的思想,发明了折半插入排序,这种排序的特点就是不再从左到右依次遍历已有有序表,而是从中间位置开始对半比较,若插入数值比中心数值大,则取右边子序列中心位置进行下一轮比较,反之则取左边子序列中心进行比较,直到找到前一个数值比其大,后一个数值比其小的位置,将该位置后的数值均向后移动一格,最后将该数值插入指定位置即可。


//@list 需排序数组
//@count 数组长度
//对半插入排序
void BinaryInsertionSort(int *list, int count) {
	for (int i = 1; i < count; i++) {
		int insertNum = list[i];
		int startLoc = 0;
		int endLoc = i;
		while (startLoc <= endLoc) {
			int middle = (startLoc + endLoc) / 2;
			if (middle == 0) {
				if (insertNum < list[middle]) {
					for (int j = i; j > middle; j--) {
						list[j] = list[j - 1];
					}
					list[middle] = insertNum;
				}
				break;
			}
			else {
				if (insertNum < list[middle] && insertNum > list[middle - 1]) {
					for (int j = i; j > middle; j--) {
						list[j] = list[j - 1];
					}
					list[middle] = insertNum;
					break;
				}
				else {
					if (insertNum < list[middle]) {
						endLoc = middle - 1;
					}
					else {
						startLoc = middle + 1;
					}
				}
			}
		}
	}
}

希尔排序

      希尔排序是一种增强版的直接插入排序,由于直接插入排序在序列中数值较多时会因为大量的移位操作从而耗费大量的时间。因此希尔排序将一个完整的无序序列按照一定的间隔分离成多个子序列,每个子序列进行直接插入排序后合并。然后不断减小间隔距离进行直接插入排序,直至间隔距离为1执行完毕(间隔为1即为普通的直接插入排序,但是由于序列已大致具有顺序,因此需要移动的次数大幅减少,从而减少了算法复杂度)。测试序列{1, 4, 2, 5, 9, 7, 8, 0, 6, 3},初始间隔设置为4,进行测试。一次排序结果为{1,3,2,0,6,4,8,5,9,7},二次排序结果为{0,3,2,1,5,4,7,6,9,8},三次排序结果为{0,1,2,3,5,4,7,6,9,8},最终结果为{0,1,2,3,4,5,6,7,8,9}。



//@list 需排序数组
//@count 数组长度
//@increasement 最大增量
//希尔排序
void ShellInsert(int *list, int count, int increasement) {
	for (int i = increasement; i > 0; i--) {
		for (int j = 0; j < i; j++) {
			for (int k = j + i; k < count; k += i) {
				int value = list[k];
				for (int m = j; m < k; m += i) {
					if (value < list[m]) {
						for (int n = k; n > m; n -= i) {
							list[n] = list[n - i];
						}
						list[m] = value;
						break;
					}
				}
			}
		}
	}
}

    
阅读更多

没有更多推荐了,返回首页