1.排序算法稳定性的概念:假若排序前序列中的两个元素R1,R2,排序前R1在R2之前,若排序后R1仍在R2之前,则称这个算法是稳定的。稳定性与算法的性能优劣无关,属于对算法性质的描述。
2.排序算法分类:
根据是否需要借助外存排序分为:内部排序和外部排序
直接插入排序
直接插入排序的思想:给定一串序列长度为n,假设前i项已经排序完毕,(一般假设第一项排序完,从第二项开始),则从第i+1项开始,每项都与前面的所有元素向比较,每次和前一位比较,若小于前一项,则与该项互换位置,相当于将其插入到了前一项的前面,知道大于等于前一项的数或者到数组边界,i++;这样遍历完一边之后数组就成了有序数组了。
C++代码实现:
#include<iostream>
using namespace std;
void direct_insert_sort(int array[],int _length)
{
int temp;
for(int i=1;i<_length;i++)
{
for(int j =i;array[j]<array[j-1]&&j>=1;j--)//第一个元素默认已经排序,从第2个元素开始,一直与前面一个元素比较,小于则插入
{
temp = array[j];
array[j] = array[j-1];
array[j-1] = temp;
}
}
cout<<"已经直接插入排序完成,数组排序后为:"<<endl;
for(int i=0;i<_length;i++)
{
cout<<array[i]<<endl;
}
}
int main(int argc,char *argv[])
{
int *arr;
int n,element;
cout<<"输入数组长度:"<<endl;
cin>>n;
arr = (int*)malloc(n*sizeof(int));
for(int i=0;i<n;i++)
{
cout<<"输入第"<<i+1<<"个元素:"<<endl;
cin>>element;
arr[i] = element;
}
direct_insert_sort(arr,n);
}
时间复杂度为O(n*2)
空间复杂度为O(1)
稳定性:稳定
适用性:适用于顺序存储或链式存储的线性表
折半插入排序
折半插入排序是插入排序的升级版,对前i项已经排序好的长度为n的有序数组,从i+1项开始,每一项直接用折半查找找到该元素应该插入的位置,然后在统一挪动(减少了与前面元素比较的次数)。数据量较小时该算法性能表现优秀。
需要注意的是与二分查找不同的是,最总确认key值的指针不是mid而是high,因为折半插入排序需要一直判断下去,直到high = low = mid,此时进行最后一步,若key>=mid,应该low+=1,high不变,否则high-=1;key应该插入的位置就在high+1处。
C++代码实现:
#include<iostream>
using namespace std;
int Binary_Search(int a[],int key,int n)//参数分别为查找数组,待插入元素的值,n表示数组的前n个元素已经是有序的
{
int high = n-1,low = 0;
int mid = (high+low)/2;
while (low<=high) {
if(key>=a[mid]) //仔细推敲一下直接插入排序的插入过程,遇到相等的元素是插入到其后面的
low=mid+1;
else
high=mid-1;
mid = (high+low)/2;
}
return high+1;
}
void