基础实在差的太多,(贴的代码太多,做的思考太少,和大佬差距越来越大,现在开始刷书也不知道到底来不来得及)
真是应了那句话,无论什么事,在结束之前,最坏的结果不过就是重头再来。
第三章初等排序
3.1挑战问题之前——排序
排序主要注意三点:
1.复杂度与稳定性(稳定是指当数据中存在2个或者2个以上键值相等的元素时,这些元素在排序处理前后顺序不变。)
2.除保存数据的数组以外是否还需要额外内存
3.输入数据的特征是否会对复杂度造成影响
3.2插入排序
数组分为两部分:一部分为已排序部分,一部分为未排序部分。
执行下述,直至未排序部分消失:
1.取出未排序部分的开头赋给变量v;
2.在已排序的的部分,将所有比v大的元素向后移动一个单位。
3.将以取出的元素插入空位
模板
int csort(int a[],int n){
int v,j;
for(int i=1;i<n;i++){
v=a[i];
j=i-1;
while(j>=0&&a[j]>v){
a[j+1]=a[j];
j--;
}
a[j+1]=v;
print(a,n);
}
}
3.3冒泡排序
重复执行下述处理,直到数组中不包含顺序相反的相邻元素
从数组末尾开始依次比较相邻的两个元素,如果大小相反则交换位置。
模板
int bsort(int a[],int n){
int flag=1;
int sw=0;//记录交换次数(又称为反序数或逆序数,可用于体现数列的错乱程度)
while(flag){
flag=0;
for(int j=n-1;j>=1;j--){
if(a[j]<a[j-1]){
swap(a[j],a[j-1]);
flag=1;
sw++;
}
}
}
}
3.4选择排序
每次找出数组中最小的数字,放置相应位置,完成排序
重复执行n-1次下述处理
1.找出未排序部分的最小值minj;
2.将minj位置的元素和未排序部分的起始元素进行交换;
模板
int ssort(int a[],int n){
int minj;
for(int i=0;i<n;i++){
minj=i;
for(int j=i;j<n;j++){
if(a[j]<a[minj]){
minj=j;
}
}
swap(a[i],a[minj]);
}
}
小结:冒泡与选择相比,一个从局部入手减少逆序数,一个全局逐个选择最小值,思路不同,但是都是“通过i次外层循环,从数据中求出i个最小值” 相对地,插入排序是通过i次外层循环,直接将原数组的i个元素重新排序。
三种排序方法都是N²的时间复杂度 插入和冒泡均是稳定排序,选择排序为不稳定排序插入排序的优势在可以快速处理相对有序的数列.
3.5稳定排序(没啥好说的,选择排序不稳定...)
3.6希尔排序
其实是插入排序的升级版?按一定区间长度排序,然后再细化?有点难...放一放..还有一篇的解释似乎挺详细.