插入排序是 稳定排序。
插入排序的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序的时间复杂度为 O(n²),虽然同样是 O(n²) 的时间复杂度,但是比冒泡排序和选择排序的性能要好一点。
思路
插入排序的思路是这样的(由小到大排序):
插入排序的排序思想类似给扑克牌排序
- 将待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列;
- 从头到尾依次遍历未排序序列,将扫描到的每个元素插入有序序列的适当位置。(若待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
C
#include<stdio.h>
void InsertionSortByWhile(int arr[], int len);
void InsertionSortByFor(int arr[], int len);
int main(void)
{
int arr[] = {20, 32, 4, 33, 72, 56, 88, 60, 46, 98};
int len = (int)sizeof(arr)/sizeof(*arr);
//使用两种方法都可以
//InsertionSortByWhile(arr, len);
InsertionSortByFor(arr, len);
int i;
for(i=0; i<len; i++)
{
printf("%d\n", arr[i]);
}
return 0;
}
//while循环方法
void InsertionSortByWhile(int arr[], int len)
{
int i;
int j;
int key;
//假设序列的第一个数是有序的
for(i=1; i<len; i++)
{
key = arr[i];
j = i-1;
while(j>=0 && (arr[j]>key))
{
arr[j+1] = arr[j];//移动数据
j--;
}
arr[j+1] = key;//插入数据
}
}
//for循环方法
void InsertionSortByFor(int arr[], int len)
{
int i;
int j;
int key;
for(i=1; i<len; i++)
{
key = arr[i];
for(j = i-1; j>=0; j--)
{
if(arr[j] > key)
{
arr[j+1] = arr[j];//移动数据
}
else
{
break;
}
}
arr[j+1] = key;//插入数据
}
}
C#
public class Program
{
public static void Main(string[] args)
{
int[] arr = { 20, 32, 4, 33, 72, 56, 88, 60, 46, 98 };
InsertionSortByWhile(arr);
//InsertionSortByFor(arr);
for (int i = 0; i < arr.Length; i++)
{
Console.WriteLine(arr[i]);
}
Console.ReadLine();
}
//while循环
public static void InsertionSortByWhile(int[] arr)
{
int i;
int j;
int key;
for (i = 1; i < arr.Length; i++)
{
key = arr[i];
j = i - 1;
while (j >= 0 && (arr[j] > key))
{
arr[j + 1] = arr[j];//移动数据
j--;
}
arr[j + 1] = key;//插入数据
}
}
//for循环
public static void InsertionSortByFor(int[] arr)
{
int i;
int j;
int key;
for (i = 1; i < arr.Length; i++)
{
key = arr[i];
for (j = i - 1; j >= 0; j--)
{
if (arr[j] > key)
{
arr[j + 1] = arr[j];//移动数据
}
else
{
break;
}
}
arr[j + 1] = key;//插入数据
}
}
}