qsort详细实现, 双向冒泡
来源:互联网 发布:rax户外鞋怎么样知乎 编辑:程序博客网 时间:2024/04/29 03:59
高级排序算法中我们将只介绍这一种,同时也是目前我所知道(我看过的资料中)的最快的。它的工作看起来仍然象一个二叉树。首先我们选择一个中间值middle程序中我们使用数组中间值,然后把比它小的放在左边,大的放在右边(具体的实现是从两边找,找到一对后交换)。然后对两边分别使用这个过程(最容易的方法——递归)。
1.快速排序:
这里我没有给出行为的分析,因为这个很简单,我们直接来分析算法:首先我们考虑最理想的情况
1.数组的大小是2的幂,这样分下去始终可以被2整除。假设为2的k次方,即k=log2(n)。
2.每次我们选择的值刚好是中间值,这样,数组才可以被等分。
第一层递归,循环n次,第二层循环2*(n/2)......
所以共有n+2(n/2)+4(n/4)+...+n*(n/n) = n+n+n+...+n=k*n=log2(n)*n
所以算法复杂度为O(log2(n)*n)
其他的情况只会比这种情况差,最差的情况是每次选择到的middle都是最小值或最大值,那么他将变成交换法(由于使用了递归,情况更糟)。但是你认为这种情况发生的几率有多大??呵呵,你完全不必担心这个问题。实践证明,大多数的情况,快速排序总是最好的。
如果你担心这个问题,你可以使用堆排序,这是一种稳定的O(log2(n)*n)算法,但是通常情况下速度要慢于快速排序(因为要重组堆)。三、其他排序
1.双向冒泡:
通常的冒泡是单向的,而这里是双向的,也就是说还要进行反向的工作。
代码看起来复杂,仔细理一下就明白了,是一个来回震荡的方式。
写这段代码的作者认为这样可以在冒泡的基础上减少一些交换(我不这么认为,也许我错了)。
反正我认为这是一段有趣的代码,值得一看。
1.快速排序:
#include <iostream.h>void run(int* pData,int left,int right){ int i,j; int middle,iTemp; i = left; j = right; middle = pData[(left+right)/2]; //求中间值 do{ while((pData[i]<middle) && (i<right))//从左扫描大于中值的数 i++; while((pData[j]>middle) && (j>left))//从右扫描大于中值的数 j--; if(i<=j)//找到了一对值 { //交换 iTemp = pData[i]; pData[i] = pData[j]; pData[j] = iTemp; i++; j--; } }while(i<=j);//如果两边扫描的下标交错,就停止(完成一次) //当左边部分有值(left<j),递归左半边 if(left<j) run(pData,left,j); //当右边部分有值(right>i),递归右半边 if(right>i) run(pData,i,right);}void QuickSort(int* pData,int Count){ run(pData,0,Count-1);}void main(){ int data[] = {10,9,8,7,6,5,4}; QuickSort(data,7); for (int i=0;i<7;i++) cout<<data[i]<<" "; cout<<"\n";}
这里我没有给出行为的分析,因为这个很简单,我们直接来分析算法:首先我们考虑最理想的情况
1.数组的大小是2的幂,这样分下去始终可以被2整除。假设为2的k次方,即k=log2(n)。
2.每次我们选择的值刚好是中间值,这样,数组才可以被等分。
第一层递归,循环n次,第二层循环2*(n/2)......
所以共有n+2(n/2)+4(n/4)+...+n*(n/n) = n+n+n+...+n=k*n=log2(n)*n
所以算法复杂度为O(log2(n)*n)
其他的情况只会比这种情况差,最差的情况是每次选择到的middle都是最小值或最大值,那么他将变成交换法(由于使用了递归,情况更糟)。但是你认为这种情况发生的几率有多大??呵呵,你完全不必担心这个问题。实践证明,大多数的情况,快速排序总是最好的。
如果你担心这个问题,你可以使用堆排序,这是一种稳定的O(log2(n)*n)算法,但是通常情况下速度要慢于快速排序(因为要重组堆)。三、其他排序
1.双向冒泡:
通常的冒泡是单向的,而这里是双向的,也就是说还要进行反向的工作。
代码看起来复杂,仔细理一下就明白了,是一个来回震荡的方式。
写这段代码的作者认为这样可以在冒泡的基础上减少一些交换(我不这么认为,也许我错了)。
反正我认为这是一段有趣的代码,值得一看。
#include <iostream.h>void Bubble2Sort(int* pData,int Count){ int iTemp; int left = 1; int right =Count -1; int t; do { //正向的部分 for(int i=right;i>=left;i--) { if(pData[i]<pData[i-1]) { iTemp = pData[i]; pData[i] = pData[i-1]; pData[i-1] = iTemp; t = i; } } left = t+1; //反向的部分 for(i=left;i<right+1;i++) { if(pData[i]<pData[i-1]) { iTemp = pData[i]; pData[i] = pData[i-1]; pData[i-1] = iTemp; t = i; } } right = t-1; }while(left<=right);}void main(){ int data[] = {10,9,8,7,6,5,4}; Bubble2Sort(data,7); for (int i=0;i<7;i++) cout<<data[i]<<" "; cout<<"\n";}快速排序#include <iostream> using namespace std; class QuickSort { public: void quick_sort(int* x,int low,int high) { int pivotkey; if(low <high) { pivotkey=partion(x,low,high); quick_sort(x,low,pivotkey-1); quick_sort(x,pivotkey+1,high); } } int partion(int* x,int low,int high) { int pivotkey; pivotkey=x[low]; while(low <high) { while (low <high&&x[high]>=pivotkey) --high; //还有while循环只执行这一句 x[low]=x[high]; while (low <high&&x[low] <=pivotkey) ++low; //还有while循环只执行这一句 x[high]=x[low]; } x[low]=pivotkey; return low; } }; int main() { int x[10]={52,49,80,36,14,58,61,97,23,65}; QuickSort qs; qs.quick_sort(x,0,9); cout <<"排好序的数字序列为:" <<endl; for (int i=0;i <10;i++) { printf("%d ",x[i]); } return 0; }
- qsort详细实现, 双向冒泡
- 用冒泡排序法实现qsort函数
- 用冒泡排序模拟实现qsort
- Java 实现双向冒泡排序
- 用冒泡排序的方法模拟实现qsort函数
- 通用冒泡排序法qsort的用法与其模拟实现
- 有关qsort的应用以及冒泡排序的实现
- 使用回调函数实现qsort(冒泡排序)
- 模仿qsort的功能实现一个通用的冒泡排序。
- PHP实现冒泡排序、双向冒泡排序算法
- 双向冒泡
- 双向冒泡
- 双向冒泡排序算法思想及C语言实现
- 双向链表操作(逆置三种实现以及 冒泡排序 )
- # Java实现冒泡排序—详细解析优化版冒泡
- 双向冒泡与奇偶冒泡
- 【C】模仿 qsort 的功能实现一个通用的冒泡排序
- 使用回调函数,模拟实现qsort(采用冒泡的方式)
- 您可能需要将当前数据库的兼容级别设置为更高的值,以启用此功能
- Android 自动控制生产线
- BloomFilter的一个简单实现(C语言)
- The list of Vim commands
- Linux输入子系统分析(一)
- qsort详细实现, 双向冒泡
- Yum安装PostgreSQL
- NSIS安装包提前释放一些文件
- 删除2个非递增链表相同的元素,并且合并为一个非递增链表
- 今天又去面试了,面试了将近四个小时
- 汉诺
- 复习笔记3 算数运算符 转义字符 转义序列 前后自增自减的区别
- linux rpm软件包管理器
- c++程序员面试题目