直接插入排序
思想:依次将待排序列中的每一个记录插入到排好的序列中,直到全部都排好序
void Sort::InsertSort(){
int i,j,temp;
for(i=1;i<length;i++){
temp=data[i];
for(j=i-1;j>=0&&temp>data[j];j--)
data[j+1]=data[j];
data[j+1]=temp;
}
}
外层循环执行n-1次,内层循环的次数取决于当前数据所在位置之前有多少个数据大于当前数据
最好情况:待排序序列为正序,每次只需要和有序序列的最后一个作比较,因为temp的存在,所以会有两次移动,
比较次数:(n-1);移动次数:2*(n-1)
最坏情况:待排序序列为逆序,每次要与前面i-1个数进行比较
比较次数:(1+(n-1))*(n-1)/2;移动次数:(n+4)(n-1)/2
插入排序需要一个辅助空间
平均时间复杂度:O(n^2)
直接插入排序是一种稳定的排序方法
希尔排序
思想:将整个待排序记录序列分割成若干个子序列,在子序列内进行直接直接插入排序,待整个序列基本有序时,在对全体进行一次直接插入排序
void Sort::ShellSort(){
int d,i,j,temp;
for(d=length/2;d>=1;d=d/2){
for(i=d;i<length;i++){
temp=data[d];
for(j=i-d;j>=0&&temp<data[j];j=j-d)
data[j+d]=data[j];
data[j+d]=temp;
}
}
}
将整个待排序记录序列分割成若干个子序列,在子序列内进行直接直接插入排序,待整个序列基本有序时,在对全体进行一次直接插入排序
1.如何分割待排子序列
2.子序列如何进行直接插入排序
第一层循环,对待排序列进行分割,直至跳跃间隔为1,此时完成排序
第二层循环,对不同划分中子序列的所有数据进行一次插入排序
第三层循环,对同一子序列中的数据进行插入排序
时间复杂度:nlog2n~n²之间,当选择合适的增量序列,时间复杂度可以达到n^1.3
由于希尔排序是跳跃式移动,所以希尔排序式不稳定的
冒泡排序
void Sort::BubbleSort(){
int j,exchange,bound,temp;
exchange=length-1;
while(exchange!=0){
bound=exchange;exchange=0;
for(j=0;j<bound;j++)
if(data[j]>data[j+1]){
temp=data[j];
data[j]=data[j+1];
data[j+1]=temp;
exchange=j;
}
}
}
两两进行比较,反序则交换,知道没有反序
最好情况:待排序列为正序,执行n-1次比较后,没有交换,完成排序
比较次数:n-1;移动次数:0
最坏情况:待排序列为逆序,执行(1+n-1)(n-1)/2次,交换3(1+n-1)(n-1)/2
比较次数:(1+n-1)(n-1)/2;移动次数:3*(1+n-1)*(n-1)/2
移动!=交换 交换(1+n-1)*(n-1)/2次,每次交换发生3次移动
冒泡排序需要一个temp暂存单元完成交换
平均时间复杂度:O(n^2)
冒泡排序是一种稳定的排序方法
快速排序
int Sort::Partition(int first,int last){
int i=first,j=last,temp;
while(i<j){
while(i<j&&data[i]<=data[j])j--;
if(i<j){
temp=data[i];
data[i]=data[j];
data[j]=temp;
i++;
}
while(i<j&&data[i]<=data[j]) i++;
if(i<j){
temp=data[i];
data[i]=data[j];
data[j]=temp;
j--;
}
}
return i;
}
void Sort::QuickSort(int first,int last){
if(first>=last) return;
else{
int pivot=Partition(first,last);
QuickSort(first,pivot-1);
QuickSort(pivot+1,last);
}
}
选定一个轴值,将待排序列记录划分成两部分,左侧记录均小于或等于轴值,右侧记录均大于等于轴值,然后重复此过程
快速排序的执行时间取决于递归的深度
最好情况:每次划分对记录定位后,该记录的左侧子序列和右侧子序列长度相等
时间复杂度:O(nlog2n)
空间复杂度:O(log2n)
最坏情况:待排序列为正序或逆序,每次划分只能的到以上一次减少一个的子序列,另一个子序列为空,此时必须经过n-1次递归
时间复杂度:O(n^2)
空间复杂度:O(n)
平均时间复杂度:O(nlog2n)
平均空间复杂度:O(log2n)
快速排序是不稳定的排序方法
简单选择排序
void Sort::SelectSort(){
int index,temp;
for(int i=0;i<length-1;i++){
index=i;
for(int j=i+1;j<length;j++)
if(data[index]>data[j]) index=j;
if(index!=i){
temp=data[i];
data[i]=data[index];
data[index]=temp;
}
}
}
第i趟排序在待排序列ri~rn(1<=i<=n-1)中选取最小的记录,并和第i个记录交换作为有序序列的第i个记录
1.在待排序列中选取最小记录
2.确定该最小记录在有序序列中的位置
最好情况:待排序列为正序,移动0次
最坏情况:待排序列为逆序,交换n-1次,移动3*(n-1)次
无论好坏,简单选择排序的比较次数始终为(1+(n-1))*(n-1)/2
平均时间复杂度:O(n²)
temp交换记录的暂存单元
简单选择排序是一种不稳定的排序方法