直接插入排序
-
基本思想: 利用顺序查找,在a[1…i-1]有的序列中查找a[i]的插入位置。
-
算法思想:
1>在顺序表中查找a[i]的位置k;
2>将a[k+1…i]的元素往后移一个位置;
3>将a[i]放在a[k]的位置上; -
优化: 可以在比较的同时进行移动,然后直接放到最终的位置。
-
算法分析: 是一种稳定的排序方法,时间复杂度为o(n2),空间复杂度为O(1)。
#include<iostream>
using namespace std;
void Sort_insert(int a[],int length);//直接插入排序
void output(int a[],int length);//输出
int main(){
int a[6]={-1,3,4,5,2,1};
Sort_insert(a,5);
output(a,5);
}
void Sort_insert(int a[],int length){
for(int i=2;i<=length;i++){
if(a[i]<a[i-1]){
a[0]=a[i];//设置监视哨
a[i]=a[i-1];//将i-1往后移
int j;
for(j=i-2;a[0]<a[j];j--){//从后往前比较
a[j+1]=a[j];
}
a[j+1]=a[0];//只有a[j]大于a[0]时,才会跳出循环,所以j+1的位置是a[0]要插入的位置
}
}
}
void output(int a[],int length){
for(int i=1;i<=length;i++)
cout<<a[i]<<" ";
cout<<endl;
}
折半插入排序
- 基本思想: 利用折半查找,在a[1…i-1]有的序列中查找a[i]的插入位置。(因为a[1…i-1]是有序的,所以可以用折半查找)
- 算法分析: 是一种稳定的排序方法,虽然比较次数减小了,但是移动次数不变,所以时间复杂度仍为O(n2),空间复杂度为O(1)。
#include<iostream>
using namespace std;
void Sort_Binsert(int a[],int length);//直接插入排序
void output(int a[],int length);//输出
int main(){
int a[6]={-1,3,4,5,2,1};
Sort_Binsert(a,5);
output(a,5);
}
void Sort_Binsert(int a[],int length){
for(int i=2;i<=length;i++){
a[0]=a[i];//设置监视哨
int low=1,high=i-1;
while(low<=high){//只有一个元素的时候也要进行比较,来确定插在这个元素的前面还是后面
int mid=(low+high)/2;
if(a[0]<a[mid])
high=mid-1;
else
low=mid+1;
}
for(int j=i-1;j>=low;j--)
a[j+1]=a[j];
a[low]=a[0];
}
}
void output(int a[],int length){
for(int i=1;i<=length;i++)
cout<<a[i]<<" ";
cout<<endl;
}
希尔排序
- 希尔排序: 又称缩小增量排序,是基于若待排序的序列为“正序”时,其时间复杂度为O(n),仅需要比较,不需要移动。所以对于一个基本有序的序列,采用希尔排序比较快。
- 基本思想: 将一个待排序的序列,分为若干个子序列然后分别进行直接插入排序,然后最后对全体进行一次直接插入排序。即先宏观调整,在微观调整
- 基本算法: 对于一个序列每个元素与相隔dk的元素进行比较。通过改变dk的值进行微调。要注意,dk的值每次应该是递减的,但最后一次一定是1,而且应该是dk增量中的值没有除了1之外的公因子。(即dk中的值不能有公因数)
#include<iostream>
using namespace std;
void Shell_Insert(int a[],int length,int dk);//希尔插入比较
void Shell_Sort(int a[],int length,int dk[],int dk_len);//希尔排序
void output(int a[],int length);//输出
int main(){
int a[6]={-1,3,4,5,2,1};
int dk[3]={-1,3,1};
Shell_Sort(a,5,dk,2);
output(a,5);
}
void Shell_Insert(int a[],int length,int dk){
for(int i=1+dk;i<=length;i++){
if(a[i]<a[i-dk]){
a[0]=a[i];
int j;
for(j=i-dk;j>0&&a[j]>a[0];j-=dk)
a[j+dk]=a[j];
a[j+dk]=a[0];
}
}
}
void Shell_Sort(int a[],int length,int dk[],int dk_len){
for(int i=1;i<=dk_len;i++)
Shell_Insert(a,length,dk[i]);
}
void output(int a[],int length){
for(int i=1;i<=length;i++)
cout<<a[i]<<" ";
}