排序算法
来源:互联网 发布:免费的顶级域名 编辑:程序博客网 时间:2024/06/08 17:00
冒泡排序
- void bubblesort(int a[], int n)
- {
- for(int i=0; i<n-1; i++)
- for(int j=0; j<n-1-i; j++)
- if(a[j]>a[j+1])
- swap(a[j],a[j+1]);
- }
- //或者
- void bubblesort(int a[], int n)
- {
- for(int i=0; i<n; i++)
- for(int j=i; j<n; j++)
- if(a[i]>a[j])
- swap(a[i],a[j]);
- }
比较次数:1+2+......+N-1
优化版冒泡排序
- void bubblesort(int a[], int n) n2
- {
- bool flag = true;
- for(int i=0; i<n-1 &&falg; i++)
- {
- flag = false;
- for(int j=1; j<n-i; j++)
- if(a[j]<a[j-1])
- {
- swap(a[j],a[j-1]);
- flag = true;
- }
- }
- }
- /* 设置一个标志域flag,如果某一趟排序发生了变换,那么flag为true。
- * 如果某一趟排序没有发生交换,则说明序列已经有序了,不必再进行继续的比较操作,此时flag为false
- */
——————————————————————————————————————————————————————————
选择排序
思想:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
- void Selectsort(int a[], int n) n2
- {
- for(int i=0; i<n-1 ; i++)
- {
- min = i;
- for(int j=i+1; j<n; j++)
- if(a[j] <a[min])
- min = j;
- }
- if(min != i)
- {
- swap(a[min], a[i]);
- }
归并排序
可以看出合并有序数列的效率是比较高的,可以达到O(n)。
插入排序
如果a[j]前一个数据a[j-1] > a[j],就交换a[j]和a[j-1],再j--直到a[j-1] <= a[j]。这样也可以实现将一个新数据新并入到有序区间,从小到大排序。
快速排序
思想
快速排序采用的思想是分治思想。
快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。
举例说明一下吧,这个可能不是太好理解。假设要排序的序列为
2 2 4 9 3 6 7 1 5 首先用2当作基准,使用i j两个指针分别从两边进行扫描,把比2小的元素和比2大的元素分开。首先比较2和5,5比2大,j左移
2 2 4 9 3 6 7 1 5 比较2和1,1小于2,所以把1放在2的位置
2 1 4 9 3 6 7 1 5 比较2和4,4大于2,因此将4移动到后面
2 1 4 9 3 6 7 4 5 比较2和7,2和6,2和3,2和9,全部大于2,满足条件,因此不变
经过第一轮的快速排序,元素变为下面的样子
[1] 2 [4 9 3 6 7 5]
之后,在把2左边的元素进行快排,由于只有一个元素,因此快排结束。右边进行快排,递归进行,最终生成最后的结果。
代码
int quicksort(int a[], int left, int right){
if(left < right){
int key = a[left];
int low = left;
int high = right;
while(low < high)
{
while(low < high && a[high] > key)
{
high--;
}
a[low] = a[high];
while(low < high && a[low] < key)
{
low++;
}
a[high] = a[low];
}
a[low] = key;
quicksort(a,left,low-1);
quicksort(a,low+1,right);
}
}
分析
快速排序的时间主要耗费在划分操作上,对长度为k的区间进行划分,共需k-1次关键字的比较。
最坏情况是每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。时间复杂度为O(n*n)
在最好情况下,每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:O(nlgn)
尽管快速排序的最坏时间为O(n2),但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快者,快速排序亦因此而得名。它的平均时间复杂度为O(nlgn)。
讲解:https://zhidao.baidu.com/question/498320427100370484.html
通俗的说:找到一个基准值,从右边找比它小的,如果是互换
从左边找比它大的,如果是互换
如果不符合了,第一轮结束,此时左右两边都重复执行如上操作
堆排序:http://www.cnblogs.com/mengdd/archive/2012/11/30/2796845.html
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- 排序算法
- Codeforces Round #377 (Div. 2) D. Exams 贪心+二分
- Xcode 8 去除打印台打印的多余日志
- 数据结构(十)循环链表和双向链表
- Windows下利用hexo和git搭建博客
- Android Studio 基本设置
- 排序算法
- 模拟鼠标事件的实现思路及代码
- 文章标题
- CF #377div2C Sanatorium
- 函数指针与指针函数的区别
- Android仿今日头条、CSDN顶部Tab布局
- nginx学习
- pycharm和sublime设置光标“上下左右”移动快捷键
- 【43.26%】【codeforces 732C】Sanatorium