【直接插入排序】
思想:插入第 i 个元素 V[i] , 前面 i-1 个元素是排好序的,将 V[i] 的值从后向前与前面 i-1 个逐一比较,大的元素往后移一位,直到空出合适的位置放入 V[i]。
步骤:1、建立一个未排序和已排序的数组,刚开始已排序数组为空,把未排序的数组中的元素一个个取出来,按顺序插到已排序数组里;
2、当排序开始后,已排序的数组元素数目加1,未排序的减1,重复插入过程直到为排序数组为空。
复杂度:
最好的情况:已排好序,每次只要和最后一个的比较一次 :O(n);
最坏的情况:倒序,与前面所有进行比较:O(n^2);
总结:适合小数组(大数组效率低);算法稳定;
源代码:
#include <iostream>
#include <stdlib.h>
using namespace std;
void insertsort(int Arr[],int length)
{
for(int i=1;i<length;i++) //遍历所有的元素
{
int insertnum=Arr[i]; //取出当前要插入的元素
int j=i-1;
while(Arr[j]>insertnum&&j>=0) //分别与排好序的数组元素进行比较,从后往前
{
Arr[j+1]=Arr[j]; //将元素往后移,空出插入位
j--; //往前移,方便插入位与前一个元素比较
}
Arr[j+1]=insertnum; //插入元素
}
}
int main()
{
int arr[5]={1,3,5,4,2};
insertsort(arr,5);
system("pause");
return 0;
}
【二分插入排序】
思想:同直接插入排序,区别是折半查找,直接插入->从后往前比较,折半查找->在已排好序的数组里选一个中间值进行比较。
性能:O( n*log(n) );平均性能高于“直接插入排序”,完全或接近有序情况下低于“直接插入排序”,n较大时用二分插入排序;算法稳定。
void InserchSort() //二分插入排序
{
for(int i=1;i<length;i++) //从第二个开始,遍历所有元素
{
int InserchNum=List[i];
int low=0; //折半查找区间的下限
int high=i-1; //折半查找区间的上限
while(low<=high)
{
int middle=(low+high)/2; //用于比较的元素位置
if(InserchNum<List[middle]) //如果V[i]<比较数
high=middle-1; //对比middle左边的区间
else low=middle+1; //否则对比middle右边的区间
}
for(int k=i-1;k>=low;k--) //low为元素当前可以插入的位置,将low以及之后的元素后移
List[k+1]=List[k];
List[low]=InserchNum;
}
}
思想:先取小于长度 L的某个值 gap(一般为L/2或,L/3+1),以此为第一个间隔,所有距离为gap值的数放在一个子序列里 (数组会分为gap个子序列);
对同一个子序列用“直接插入排序“,然后按规律缩小gap的值直到为1(相当于子序列合并为大序列);
刚开始间隔较大,子序列元素少,排序快,后来间隔小,序列大,但由于前期排序了,减轻工作量;
性能:实现了跳跃式移动,从而提高算法效率;最坏:O(n^2);算法不稳定。
#include<iostream>
#include<stdlib.h>
using namespace std;
void shellsort(int ptr[],int length)
{
int increment=length;
while(increment>1)
{
increment=increment/2;
for(int i=0;i<increment;i++) //遍历增量(increment)个子序列
{
for(int j=i+increment;j<length;j+=increment) //遍历每个子序列里的所有元素
{
int insernum=ptr[j];
int k=j-increment;
while(k>=0&&insernum<ptr[k]) //直接插入排序
{
ptr[k+increment]=ptr[k];
k-=increment;
}
ptr[k+increment]=insernum;
}
}
} }
int main()
{
int a[9]={1,4,2,7,3,8,5,6,9};
shellsort(a,9);
for(int i=0;i<9;i++)
cout<<a[i]<<endl;
system("pause");
return 0;
}
【希尔排序—代码备份】
void s_Sort()
{
int gap=slength/2; //初始值为长度一半
while(gap) //只要间距大等于1,直接插入排序
{
for(int i=gap;i<slength;i++) //从子序列的第二个元素开始,遍历子序列所有的元素(这里不是每个子序列分别遍历,是遍历完所有子序列的第二个值,第三个值,直到数组结束)
{
int Insertnum=sList[i];
int k=i-gap; // “当前序列”插入元素的前一个元素;
while(k>=0&&sList[k]>Insertnum)
{
sList[k+gap]=sList[k]; //后移
k-=gap; //遍历插入元素所在序列的,前面的所有元素
}
sList[k+gap]=Insertnum;
}
gap/=2; //缩小一半
}
}
【直接插入排序—代码备份】
封装和调用
Insertsort.h
#include<vector>
using namespace std;
class Insertsort
{
private:
int length;
vector<int> List;
public:
Insertsort(vector<int> _List,int num);
void Sort();
void Printf();
};
Insertsort.cpp
#include<vector> #include<iostream> #include "Insertsort.h" using namespace std; Insertsort::Insertsort(vector<int> _List,int num) { for(int i=0;i<num;i++) List.push_back(_List[i]); length=num; } void Insertsort::Sort() { int insertnum; for(int i=1;i<length;i++) { insertnum=List[i]; int j=i; while((j!=0)&&(List[j-1]>insertnum)) { List[j]=List[j-1]; j--; } List[j]=insertnum; } } void Insertsort::Printf() { for(int i=0;i<length;i++) cout<< List[i]<<endl; }
main.cpp
#include<vector> #include<iostream> #include "Insertsort.h" #define GET_LEN(a,len){len=(sizeof(a)/sizeof(a[0]));} using namespace std; int main() { int a[]={1,4,5,2,6,3,9,6,7,0}; int len; GET_LEN(a,len) vector<int> myvector(a,a+len); Insertsort insertsort(myvector,len); insertsort.Printf(); insertsort.Sort(); insertsort.Printf(); system("pause"); return 0; }