冒泡排序
基本思想:每趟排序考虑相邻的两个数,如果顺序则考虑下两个数,如果逆序就swap一下,这样每一趟排序都可以让最“重”的数下降到边缘,n个数需要进行n-1次排序。
(写法有好多种)
void bubble_sort(int n){
for(int i=1;i<=n-1;i++){
bool flag = 0;
for(int j=1;j<=n-i;j++){
if(arr[j]>arr[j+1]){
flag = 1;
swap(arr[j],arr[j+1]);
}
}
if(!flag) break;
}
}
算法分析:
时间复杂度:O(n^2)
空间复杂度:O(1)
最好情况,初始有序,只比较了n-1次,移动次数为0;最坏情况,初始逆序,第i趟比较n-i次,每次比较后又要swap交换(记为3次),总的比较此时为n(n-1)/2,总的移动次数为3n(n-1)/2
特点是比较稳定。
快速排序
基本思想:
步骤:
1、选择数组最左边的数作为标签,然后两个指针low和high,分别指向当前数组的左边界和右边界。
2、在满足low<high的前提下,low从左向右搜索,知道找到大于标签数为止,high从右向左搜索,直到找到小于arr[0]的数位置(或者low和high相遇),然后swap一下。
3、步骤2的结束条件一定是high = low,然后,我们再把我们的标签放到arr[low]和arr[low]交换一下就好了。
void q_sort(int q[],int left,int right){
if(low>=high) return ;
int tmp = q[low];
int low = left;
int high = right;
while(low<high){
while(low<high&&q[high]>=tmp) high--;
q[low] = q[high];//来到这一步说明在右边找到了一个比tmp小的数,应该把它放到左边
while(low<high&&q[low]<=tmp) low++;
q[high] = q[low];//说明找到了一个比tmp大的数,应该放到右边,直接就可以了,
// 因为q[high]中的数据已经被挪到了左边原来low的位置了。
}
q[low] = tmp;
q_sort(q,left,low-1);//low左边都是比q[low]小的
q_sort(q,low+1,right);//low右边都是比q[low]大的
}
算法分析:
空间复杂度:需要借助递归栈,复杂度与递归深度有关,最好情况是O(log2n),最坏情况是O(n),平均情况下是O(log2n)。
时间复杂度:与枢纽的选择有关,最坏情况下初始序列基本有序,O(n^2),最好情况下O(nlog2n)。平均情况接近最好情况。
特点:不稳定,适合顺序结构,很难用于链式结构(难用,但是可以用)。平均性能最优,适合初始无序,n较大的情况。
对于快排的优化的基本思想是尽量选择可以将排列数组切分成两个长度尽可能相等的子序列,比如选择“三者取中”