交换排序:冒泡排序、选择排序【排序算法】
2015-09-08 18:02
495 查看
冒泡排序基本思想:
在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
快速排序基本思想:
1)选择一个基准元素,通常选择第一个元素或者最后一个元素,
2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。
3)此时基准元素在其排好序后的正确位置
4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;快速排序是一个不稳定的排序方法。
快速排序之所比较快,因为相比冒泡排序,每次交换是跳跃式的。每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。这样在每次交换的时候就不会像冒泡排序一样每次只能在相邻的数之间进行交换,交换的距离就大的多了。因此总的比较和交换次数就少了,速度自然就提高了。当然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最差时间复杂度和冒泡排序是一样的都是O(N2),它的平均时间复杂度为O(NlogN)。
各排序算法比较:
代码如下,亲测有效:
在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
快速排序基本思想:
1)选择一个基准元素,通常选择第一个元素或者最后一个元素,
2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。
3)此时基准元素在其排好序后的正确位置
4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;快速排序是一个不稳定的排序方法。
快速排序之所比较快,因为相比冒泡排序,每次交换是跳跃式的。每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。这样在每次交换的时候就不会像冒泡排序一样每次只能在相邻的数之间进行交换,交换的距离就大的多了。因此总的比较和交换次数就少了,速度自然就提高了。当然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最差时间复杂度和冒泡排序是一样的都是O(N2),它的平均时间复杂度为O(NlogN)。
各排序算法比较:
代码如下,亲测有效:
#include <iostream> using namespace std; void swap(int *, int *); void print(int[], int); void bubbleSort(int[], int); void bubbleSort2(int[], int); void bubbleSort3(int[], int); void quickSort1(int[], int, int); void quickSort2(int[], int, int, int); int main(void){ int arr[10] = { 49, 38, 65, 97, 76, 13, 27, 49, 55, 04 }; cout << "Original Array: " << endl; print(arr, 10); bubbleSort3(arr, 10); cout << "bubbleSort results: " << endl; print(arr, 10); quickSort2(arr, 0, 9, 8); cout << "quickSort results: " << endl; print(arr, 10); return 0; } //打印数组 void print(int a[], int n){ for (int index = 0; index < n; ++index) cout << a[index] << " "; cout << endl; } //交换 void swap(int *num1, int *num2){ int tmp = *num1; *num1 = *num2; *num2 = tmp; } //冒泡排序 void bubbleSort(int array[], int n){ for (int i = 0; i < n; ++i) for (int j = 1; j < n - i;++j) if (array[j] < array[j - 1]) swap(array[j], array[j - 1]); } //冒泡排序2,设置一个标志位flag,当在排序到某一刻已经没有交换的时候,说明已经有序,把flag置为false,退出排序 void bubbleSort2(int array[], int n){ bool flag = true; int sizeOfArray = n; while (flag){ flag = false; for (int j = 1; j < sizeOfArray; ++j){ if (array[j - 1] > array[j]){ swap(array[j], array[j - 1]); flag = true; } } --sizeOfArray; } } //冒泡排序3,记录每次排序最后一次交换元素的位置,在这个位置之后一定是有序的,无需再排,只需排此位置之前的 void bubbleSort3(int array[], int n){ int flag = n; while (flag > 0){ int sizeOfUnsorted = flag;//上次排序最后一次交换的位置 flag = 0; for (int index = 1; index < sizeOfUnsorted; ++index){ if (array[index - 1] > array[index]){ swap(array[index - 1], array[index]); flag = index; } } } } //快速排序1 void quickSort1(int array[], int left, int right){ if (left < right){ int i = left, j = right; int base = array[left]; //将最左边的数作为基准书,保存在base中 while (i < j){ while (i < j && array[j] >= base) //从右向左找第一个比base小的数,找到之后放到base的左边(与base交换) --j; while (i < j && array[i] <= base) //从左向右找第一个比base大的数,找到之后放到base的右边(与base交换) ++i; if (i < j) swap(array[i], array[j]); } // array[left] = array[i]; // array[i] = base; quickSort1(array, left, i - 1); //递归调用 quickSort1(array, i + 1, right); } } //快速排序2 void quickSort2(int array[], int left, int right, int k){ if (right - left > k){ int i = left, j = right; int base = array[left]; //将最左边的数作为基准书,保存在base中 while (i < j){ while (i < j && array[j] >= base) //从右向左找第一个比base小的数,找到之后放到base的左边(与base交换) --j; while (i < j && array[i] <= base) //从左向右找第一个比base大的数,找到之后放到base的右边(与base交换) ++i; if (i < j) swap(array[i], array[j]); } // array[left] = array[i]; // array[i] = base; quickSort2(array, left, i - 1, k); //递归调用 quickSort2(array, i + 1, right, k); } for (int index = 1; index <= right; ++index){ //此时的序列已基本有序,再用插入排序对基本有序序列排序 int tmp = array[index]; int j = index - 1; if (tmp < array[j]){ array[j + 1] = array[j]; --j; } array[j + 1] = tmp; } }
</pre><pre name="code" class="cpp">
<span style="font-family:Microsoft YaHei;font-size:14px;">运行结果:</span>
<img src="http://img.blog.csdn.net/20150908194202423?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
相关文章推荐
- IOS第一天多线程-05GCD队列的使用
- ORA-01033
- js 倒计时
- (总结)Nginx与Apache、Tomcat、Resin动静分离核心配置
- Winform客户端引用WCF客户端后,部分类无法正常使用
- 移动端字体大小单位rem
- Winform客户端引用WCF客户端后,部分类无法正常使用
- 2016届校招 百度WEB前端研发【实习生+提前批】面试经历
- Openwrt 之GPS调试
- ACM —— 1008 Maya Calendar
- mysql 修改列
- iOS 播放器 或直播添加 弹幕
- POJ 3660 Cow Contest
- 姿势体系结构的详细解释 -- C
- java 实现微信搜索附近人功能
- Jquery点击事件隐藏显示菜单
- IOS第一天多线程-04GCD通信
- uitableview 刷新一行
- (总结)Nginx/LVS/HAProxy负载均衡软件的优缺点详解
- 点击a链接下载附件代码