分治思想的应用:C++实现快速排序和随机化的快速排序

原创 2014年09月08日 14:04:49
  • 947

1. 快速排序时冒泡排序的升级版

都知道冒泡排序需要从0-n-1轮n-1次两两比较。并且进行多次两两交换才能得到最后的排列结果。需要

for(i from 0 to n-1)

for(j from i+1 to n-1)

compare(a[i], a[j])  and switch(a[i], a[j])

算法复杂度为O(n power 2)

快速排序通过对冒泡的改进,j将i和j从两边移到中间,使得第一次循环结果为以选取的中心值为中心。如果需要升序,

left = 0, right = n-1, pivot = a[left]

while(i< =j)

{

if(a[j]<pivot) a[i]= a[i] , i++小的往左边移动

if(a[i]>pibot) a[j] = a[j], j++, 大的往右移动

else i++

else j++

}

quicksort(a,left,i-1);

quicksort(a,i+1,right);

快速排序则添加入循环迭代思想, 不断的拆分这个数组。

①选取中心元素的问题

选取第一个数为中心元素

②如何划分问题
③如何重复步骤①②将所有数据排序

使用递归

函数头:quicksort(inta[],intleft,intright)

①初始化:i=left;j=right;inttemp=a[left];
②划分:do{一次划分} while(i<j);
③中心元素填入:a[i]=temp;
④递归地对剩余段作快速排序

quicksort(a,left,i-1);

quicksort(a,i+1,right);

2. 如何随机排列数列?

用这个 random_shuffle() 可以得到一个随即排序:
先用数组构造一个 vector 容器,
然后给 random_shuffle() 算法传递容易的首尾迭代器即可

参考地址: http://www.cnblogs.com/afarmer/archive/2011/05/01/2033715.html

如何从一个数列中随机得到一个数?

#include <iostream> 
#include <stdlib.h> 
#include <time.h>  
using namespace std;  
int main() 
{  
srand((unsigned)time(NULL));  
for(int i = 0; i < 10;i++ )  
        cout << rand() << '\t';  
cout << endl;  
return 0; 
}

产生一定范围随机数的通用表示公式 
要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 
要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a

3.下面实现随机化的快速排序

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. using namespace std;
  6. bool static Inc(const int& x, const int& y)
  7. {
  8. return x<y;
  9. }
  10. bool static Dec(const int& x, const int& y)
  11. {
  12. return x>y;
  13. }
  14. //template<bool  cmp(const int&, const int&)>
  15. void quicksort(int a[],int left,int right)
  16. {   int i,j;
  17. if(left<right)
  18. {   i=left;j=right;
  19. int temp=a[left]; //store the pivot number, it can be anyone of the array a[]
  20. do
  21. {   while(Inc(a[j],temp) && i<j)//Inc for des
  22. j--; //j一直减直到可以交换
  23. if(i<j)
  24. {   a[i]=a[j];//blank postion i = a[j]
  25. i++;
  26. }
  27. while(Inc(temp, a[i]) && i<j)//i一直加直到a[i]大于j
  28. i++;
  29. if(i<j)
  30. {   a[j]=a[i];
  31. j--;
  32. }
  33. }while(i<j);// do while can make sure the i=j will be executed
  34. a[i]=temp;//i =j, only one positon left, so its the last temp
  35. quicksort(a,left,i-1);
  36. quicksort(a,i+1,right);
  37. }
  38. }
  39. int main()
  40. {
  41. cout<<"input n"<<endl;
  42. int n;
  43. scanf("%d",&n);
  44. int a[100];
  45. cout<<"input "<< n<<" numbers"<<endl;
  46. for(int i = 0; i< n; i++)
  47. {
  48. scanf("%d", a+i);
  49. }
  50. int left = 0, right = n-1;
  51. srand(time(NULL));
  52. left = rand()%n;
  53. cout<<"random pivot is "<<a[left]<<endl;
  54. //swap with the first one
  55. int tmp;
  56. tmp = a[0];
  57. a[0]= a[left];
  58. a[left] = tmp;
  59. quicksort(a,0,n-1);
  60. cout<<"the result is:"<<endl;
  61. for(int i = 0; i< n; i++)
  62. {
  63. cout<<a[i]<<" ";
  64. }
  65. system("pause");
  66. return 0;
  67. }
  1. 或者<pre name="code" class="cpp">   if(left<right)
  2. {   i=left;j=right;
  3. int pivot = a[left]; //store the pivot number, it can be anyone of the array a[]
  4. while(i <= j)
  5. {
  6. if(Inc(a[j],pivot) && i<j)
  7. {
  8. a[i] = a[j]; //大的往左边移动
  9. i++;
  10. if(Inc(pivot, a[i]) && i<j)
  11. {
  12. a[j] = a[i];//小的往右边移动
  13. j--;
  14. }
  15. else
  16. {
  17. i++;
  18. }
  19. }
  20. else
  21. {
  22. j--;
  23. }
  24. }
  25. a[i]=pivot;//i =j, only one positon left, so its the last temp
  26. quicksort(a,left,i-1);
  27. quicksort(a,i+1,right);
  28. }

4. 快速排序的变体

注意最后是交换a[i] 和A[r] 不是i+1

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. using namespace std;
  6. bool static Inc(const int& x, const int& y)
  7. {
  8. return x<y;
  9. }
  10. bool static Dec(const int& x, const int& y)
  11. {
  12. return x>y;
  13. }
  14. //template<bool  cmp(const int&, const int&)>
  15. void quicksort(int a[], int left, int right)
  16. {   int i,j;
  17. if(left < right)
  18. {
  19. i=left;//j=size -1;
  20. int pivot = a[left];
  21. int tmp;
  22. //int temp=a[i]; //store the pivot number, it can be anyone of the array a[]
  23. for(j = i+1; j <= right; j++)
  24. {
  25. if(a[j]<pivot)
  26. {
  27. if(j> ++i)
  28. {
  29. tmp = a[j];
  30. a[j] = a[i];//sawp i+1 and j
  31. a[i]=tmp;
  32. }
  33. }
  34. }
  35. tmp = a[i];
  36. a[i] = a[left];
  37. a[left] = tmp;
  38. quicksort(a,left,i-1);
  39. quicksort(a,i+1,right);
  40. }
  41. }
  42. int main()
  43. {
  44. cout<<"input n"<<endl;
  45. int n;
  46. scanf("%d",&n);
  47. int a[100];
  48. cout<<"input "<< n<<" numbers"<<endl;
  49. for(int i = 0; i< n; i++)
  50. {
  51. scanf("%d", a+i);
  52. }
  53. int left = 0, right = n-1;
  54. srand(time(NULL));
  55. left = rand()%n;
  56. cout<<"random pivot is "<<a[left]<<endl;
  57. //swap with the first one
  58. int tmp;
  59. tmp = a[0];
  60. a[0]= a[left];
  61. a[left] = tmp;
  62. quicksort(a,0,n-1);
  63. cout<<"the result is:"<<endl;
  64. for(int i = 0; i< n; i++)
  65. {
  66. cout<<a[i]<<" ";
  67. }
  68. system("pause");
  69. return 0;
  70. }

分治思想的应用:C++实现快速排序和随机化的快速排序的更多相关文章

  1. 分治思想--快速排序解决TopK问题

    ----前言 ​ 最近一直研究算法,上个星期刷leetcode遇到从两个数组中找TopK问题,因此写下此篇,在一个数组中如何利用快速排序解决TopK问题. 先理清一个逻辑解决TopK问题→快速排序→递 ...

  2. Big Data(一)分治思想

    按照课程安排,接下来半年,我将会去上一个为期半年的大数据课程.第一课是马士兵老师机构的周老师所讲,这里单纯记录讲课的内容. 问题1: 我有一万个元素(比如数字或单词)需要存储? 如果查找某一个元素,最 ...

  3. 快速排序 Java实现的快速排序

    快速排序  Java实现的快速排序: package xc; import java.util.Arrays; import java.util.Random; /** * * @author dax ...

  4. 快速排序改进——3区快速排序(3-way quicksort)

    1.快速排序缺陷 快速排序面对重复的元素时的处理方法是,把它放在了左部分数组或右部分数组,下次进行分区时,还需检测它.如果需要排序的数组含有大量重复元素,则这个问题会造成性能浪费. 解决方法:新增一个 ...

  5. 无序数组中用 快速排序的分治思想 寻找第k大元素

    #include <stdio.h> int *ga; int galen; void print_a(){ ; i < galen; i++){ printf("%d & ...

  6. bzoj3672/luogu2305 购票 (运用点分治思想的树上cdq分治+斜率优化dp)

    我们都做过一道题(?)货币兑换,是用cdq分治来解决不单调的斜率优化 现在它放到了树上.. 总之先写下来dp方程,$f[i]=min\{f[j]+(dis[i]-dis[j])*p[i]+q[i]\} ...

  7. 分治思想 特别常用 Codeforces Beta Round #80 (Div. 1 Only) D

    D. Time to Raid Cowavans time limit per test 4 seconds memory limit per test 70 megabytes input stan ...

  8. 快速排序基本思想,递归写法,python和java编写快速排序

    1.基本思想 快速排序有很多种编写方法,递归和分递归,分而治之法属于非递归,比递归简单多了.在这不使用代码演示.下面我们来探讨一下快速排序的递归写法思想吧. 设要排序的数组是A[0]……A[N-1], ...

  9. 分治思想求解X的M次幂方

    package main import ( "fmt" ) //递归形式分治求解 func power(x, m int) int { { } else { y := power( ...

随机推荐

  1. Eclipse与Tomcat的集成(无插件)

    1.下载Eclipse(https://www.eclipse.org/downloads/)和Tomcat(http://tomcat.apache.org/),具体的安装略: 2.打开Eclips ...

  2. maven install 找不到自定义jar包

    解决方案是在Prefernces-->Maven-->user Settings 里面点击Update settings 然后就好了.因为默认你配置settings.xml指向你的类库的时 ...

  3. 虚拟机开启Linux时出现“我以复制虚拟机”、“我已移动虚拟机”

    当出现标题的情况时,并且网络出现状况时,可以尝试一下解决办法 首先用ifconfig -a命令调出现在的网卡驱动的名称和HWaddr地址,然后再编辑/etc/sysconfig/networking/ ...

  4. MapReduce-读取HBase

    MapReduce读取HBase数据 代码如下 package com.hbase.mapreduce; import java.io.IOException; import org.apache.h ...

  5. Apache Phoenix的Join操作和优化

    估计Phoenix中支持Joins,对很多使用Hbase的朋友来说,还是比较好的.下面我们就来演示一下. 首先看一下几张表的数据: Orders表: OrderID CustomerID ItemID ...

  6. mini6410基于linux2.6.36内核通过NFS启动根文件系统总结(一搭建开发环境——建立NFS服务器)

    http://blog.csdn.net/yinjiabin/article/details/7489030 建立 nfs 服务器 在嵌入式 linux 开发的时候,常常需要使用 nfs 以方便程序的 ...

  7. java创建多线程的三种方式

    /***************************继承Thread类创建多线程************************/ public class FirstThread extends ...

  8. openstack Neutron分析(3)—— neutron-dhcp-agent源码分析

    1.neutron dhcp3个主要部件分别为什么?2.dhcp模块包含哪些内容?3.Dnsmasq配置文件是如何创建和更新的?4.DHCP agent的信息存放在neutron数据库的哪个表中? 扩 ...

  9. hibernate学习(3)

    0 列表功能实现 1 表与表之间关系回顾 (1)一对多(客户和联系人) (2)多对多(用户和角色) 2 hibernate 一对多操作 (1)一对多映射配置 (2)一对多级联保存 (3)一对多级联删除 ...

  10. js中出现问题--Type Syntax error on token "catch", Identifier expected jquery.js

    解决方案: 1.选中jQuery报错的web工程: 2.右键-->Myeclipse-->Exclude From Validation,选中: 3.继续右键Myeclipse--> ...