这里介绍两种插入排序算法:
1、直接插入排序
2、希尔排序
基本思想:
1、直接插入排序:直接插入排序即从数据第二个数开始进行比较,当它比前一个值小时,将它不断向前移动,知道它的值不再比它前面的值大,被他超过的值依次向后移动一位,如此反复,知道最后一个数排序完毕,即可得到排序后的序列。插入排序与打扑克时整理手上的牌非常类似。摸来的第1张牌无须整理,此后每次从桌上的牌(无序区)中摸最上面的1张并插入左手的牌(有序区)中正确的位置上。为了找到这个正确的位置,须自左向右(或自右向左)将摸来的牌与左手中已有的牌逐一比较。
2、希尔排序:希尔排序类似直接插入排序,但不同的是希尔排序在对序列进行排序之前会对序列进行分组,先对每一组进行排序,然后逐渐减小组距,在次进行排序,直到最后组距为1时,就是直接插入排序了,这样就可以得到排序后的序列。排序过程模拟:http://student.zjzk.cn/course_ware/data_structure/web/flashhtml/shell.htm。注意希尔排序最后的一个组距必须为1;它是不稳定排序。
1、直接插入排序:
#include <iostream>
#include <vector>
using namespace std;
//输出函数
void sort(vector<int> &L)
{
int size = L.size();
for(int i=1; i<size; i++)
{
int t = i;
int tmp;
while (t>0 && L[t]<L[t-1])
{
tmp = L[t];
L[t] = L[t-1];
L[t-1] = tmp;
t--;
}
}
}
int main()
{
int a[] = {1,6,3,4,2,1,6,9,5,3};
vector<int> v;
for(int i=0; i<10; i++)
v.push_back(a[i]);
sort(v);
for(int j=0; j<10; j++)
cout << v[j] << " ";
return 0;
}
2、希尔排序:
//希尔排序, 改进的直接插入排序
#include <iostream>
#include <vector>
using namespace std;
//#define N 20
const int N = 20; //定义常量
//输出函数
void disp(vector<int> vec)
{
cout << "排列顺序为:";
for(int i = 0; i < N; i++)
{
cout << vec[i] << " ";
}
cout << endl;
}
void shell( vector<int> &vec);
//注意向量参数为引用类型,不然无法输出排序后结果
void shellstep(vector<int> &vec, int d);
int main()
{
vector<int> vec1(N);
int a[N] = {2 ,19 ,3 ,25 ,4 ,0,8,22,10,2,9,45,12,16,21,41,6,18,34,10};
for(int i = 0; i < N; i++)
{
vec1[i] = a[i];
}
disp(vec1);
shell(vec1);
disp(vec1);
return 0;
}
void shell(vector<int>&vec) //循环分组间隔
{
int st = 3;
do{
st = st/3 + 1;
shellstep(vec, st);
}while(st>1);
}
void shellstep(vector<int>&vec, int d)
//从第一个元素开始,每隔d个距离取一个元素,对这些元素进行直接插入排序
{
for(int i = d; i < N; i++) //若比前一个大,则往前移位,前面的数往后移位,直接插入法为d = 1 的特殊情况
{
int temp,j;
if(vec[i] < vec[i-d])
{
temp = vec[i]; //待插入数副本,找到插入位置时进行赋值
j = i-d;
do{
vec[j+d] = vec[j];
j = j - d;
}while(j>=0 && temp < vec[j] );
//主要while与do while 的条件判断模式
vec[j+d] = temp;
}
}
}