排序问题
输入: n个数的一个序列< A1,A2 , … , An >。
输出: 序列的一个排列< A1’ , A2’ , … , An’ >, 满足A1’ <= A2’ <= … <= An’ , 或者 A1’>= A2’ >= … >= An’ 。
插入排序
1. 原理简述
- 在未排序的数中取出一个数(从乱糟糟的牌堆里拿出一张牌)
- 将它插入到已经排好序的子集的正确位置中(将它插入手中已经排好顺序的牌中,得到新的排好顺序的牌)
- 再取出一个数,将它插入到正确位置(再从乱糟糟的牌堆里拿出一张牌)
- 依次类推,直到序列里所有的数都插入到正确的位置。
2. 伪代码
INSERTION_SORT(A)
for j = 2 to A.length
key = A[j]
//insert A[j] into the sorted sequence A[0...j-1]
i = j-1
while i > 0 and A[i] > key
A[i+1] = A[i]
i = i-1
A[i+1] = key
3. 理解伪代码
- 假设数组下标从1 开始,数组总共有n个数。
- 排序方式是 升序排序
- 对于序列中的第2至最后一个数,我们从取出第j个数(j 从 2 到 n),将其保存在一个 key 临时变量中,这样,第j个位置就‘空’了出来。
- 对于A[0…j-1], 最开始时是[ A1 ], 只有一个数,所以它必定是排好序的。
- 从第 j-1 到 第1 个数,依次和 key 比较,如果大于key ,那就把它搬到右边的位置。
- 当不再有 大于key 的数时,空出来的位置刚好是最适合key的,将key 插进去,便得到一个新的排好顺序的序列。
循环执行以上步骤,直到将第n 个数插入到正确的位置。
对于 A[5,2,4,6,1,3] 的排序,过程如下图所示
4. C语言实现
整型数的插入排序,输出结果可选择升序或降序
- 头文件, sort.h
#ifndef __SORT_H__
#define __SORT_H__
void Insert_Sort_Integer(int array[], int length, unsigned char isAscending);
#endif
- C 文件, sort.c
#include "sort.h"
/* 插入排序 */
void Insert_Sort_Integer(int array[], int length, unsigned char isAscending)
{
int i, j;
int temp;
for (i = 1;i < length; i++)
{
temp = *(array + i);
j = i - 1;
if(isAscending)
{
while (j >= 0 && *(array + j) > temp)
{
array[j + 1] = array[j];
j--;
}
}
else
{
while (j >= 0 && *(array + j) < temp)
{
array[j + 1] = array[j];
j--;
}
}
*(array + j + 1) = temp;
}
}
结语
插入排序属于原址排序,但它的时间复杂度是O(n^2),和冒泡排序同样的时间复杂度,效率比较低,使用较少, 后面将介绍 归并排序,堆排序,快速排序