分治思想的应用:C++实现快速排序和随机化的快速排序
分治思想的应用:C++实现快速排序和随机化的快速排序
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)
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.下面实现随机化的快速排序
- #include <iostream>
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- using namespace std;
- bool static Inc(const int& x, const int& y)
- {
- return x<y;
- }
- bool static Dec(const int& x, const int& y)
- {
- return x>y;
- }
- //template<bool cmp(const int&, const int&)>
- void quicksort(int a[],int left,int right)
- { int i,j;
- if(left<right)
- { i=left;j=right;
- int temp=a[left]; //store the pivot number, it can be anyone of the array a[]
- do
- { while(Inc(a[j],temp) && i<j)//Inc for des
- j--; //j一直减直到可以交换
- if(i<j)
- { a[i]=a[j];//blank postion i = a[j]
- i++;
- }
- while(Inc(temp, a[i]) && i<j)//i一直加直到a[i]大于j
- i++;
- if(i<j)
- { a[j]=a[i];
- j--;
- }
- }while(i<j);// do while can make sure the i=j will be executed
- a[i]=temp;//i =j, only one positon left, so its the last temp
- quicksort(a,left,i-1);
- quicksort(a,i+1,right);
- }
- }
- int main()
- {
- cout<<"input n"<<endl;
- int n;
- scanf("%d",&n);
- int a[100];
- cout<<"input "<< n<<" numbers"<<endl;
- for(int i = 0; i< n; i++)
- {
- scanf("%d", a+i);
- }
- int left = 0, right = n-1;
- srand(time(NULL));
- left = rand()%n;
- cout<<"random pivot is "<<a[left]<<endl;
- //swap with the first one
- int tmp;
- tmp = a[0];
- a[0]= a[left];
- a[left] = tmp;
- quicksort(a,0,n-1);
- cout<<"the result is:"<<endl;
- for(int i = 0; i< n; i++)
- {
- cout<<a[i]<<" ";
- }
- system("pause");
- return 0;
- }
- 或者<pre name="code" class="cpp"> if(left<right)
- { i=left;j=right;
- int pivot = a[left]; //store the pivot number, it can be anyone of the array a[]
- while(i <= j)
- {
- if(Inc(a[j],pivot) && i<j)
- {
- a[i] = a[j]; //大的往左边移动
- i++;
- if(Inc(pivot, a[i]) && i<j)
- {
- a[j] = a[i];//小的往右边移动
- j--;
- }
- else
- {
- i++;
- }
- }
- else
- {
- j--;
- }
- }
- a[i]=pivot;//i =j, only one positon left, so its the last temp
- quicksort(a,left,i-1);
- quicksort(a,i+1,right);
- }
4. 快速排序的变体
注意最后是交换a[i] 和A[r] 不是i+1
- #include <iostream>
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- using namespace std;
- bool static Inc(const int& x, const int& y)
- {
- return x<y;
- }
- bool static Dec(const int& x, const int& y)
- {
- return x>y;
- }
- //template<bool cmp(const int&, const int&)>
- void quicksort(int a[], int left, int right)
- { int i,j;
- if(left < right)
- {
- i=left;//j=size -1;
- int pivot = a[left];
- int tmp;
- //int temp=a[i]; //store the pivot number, it can be anyone of the array a[]
- for(j = i+1; j <= right; j++)
- {
- if(a[j]<pivot)
- {
- if(j> ++i)
- {
- tmp = a[j];
- a[j] = a[i];//sawp i+1 and j
- a[i]=tmp;
- }
- }
- }
- tmp = a[i];
- a[i] = a[left];
- a[left] = tmp;
- quicksort(a,left,i-1);
- quicksort(a,i+1,right);
- }
- }
- int main()
- {
- cout<<"input n"<<endl;
- int n;
- scanf("%d",&n);
- int a[100];
- cout<<"input "<< n<<" numbers"<<endl;
- for(int i = 0; i< n; i++)
- {
- scanf("%d", a+i);
- }
- int left = 0, right = n-1;
- srand(time(NULL));
- left = rand()%n;
- cout<<"random pivot is "<<a[left]<<endl;
- //swap with the first one
- int tmp;
- tmp = a[0];
- a[0]= a[left];
- a[left] = tmp;
- quicksort(a,0,n-1);
- cout<<"the result is:"<<endl;
- for(int i = 0; i< n; i++)
- {
- cout<<a[i]<<" ";
- }
- system("pause");
- return 0;
- }
分治思想的应用:C++实现快速排序和随机化的快速排序的更多相关文章
- 分治思想--快速排序解决TopK问题
----前言 最近一直研究算法,上个星期刷leetcode遇到从两个数组中找TopK问题,因此写下此篇,在一个数组中如何利用快速排序解决TopK问题. 先理清一个逻辑解决TopK问题→快速排序→递 ...
- Big Data(一)分治思想
按照课程安排,接下来半年,我将会去上一个为期半年的大数据课程.第一课是马士兵老师机构的周老师所讲,这里单纯记录讲课的内容. 问题1: 我有一万个元素(比如数字或单词)需要存储? 如果查找某一个元素,最 ...
- 快速排序 Java实现的快速排序
快速排序 Java实现的快速排序: package xc; import java.util.Arrays; import java.util.Random; /** * * @author dax ...
- 快速排序改进——3区快速排序(3-way quicksort)
1.快速排序缺陷 快速排序面对重复的元素时的处理方法是,把它放在了左部分数组或右部分数组,下次进行分区时,还需检测它.如果需要排序的数组含有大量重复元素,则这个问题会造成性能浪费. 解决方法:新增一个 ...
- 无序数组中用 快速排序的分治思想 寻找第k大元素
#include <stdio.h> int *ga; int galen; void print_a(){ ; i < galen; i++){ printf("%d & ...
- bzoj3672/luogu2305 购票 (运用点分治思想的树上cdq分治+斜率优化dp)
我们都做过一道题(?)货币兑换,是用cdq分治来解决不单调的斜率优化 现在它放到了树上.. 总之先写下来dp方程,$f[i]=min\{f[j]+(dis[i]-dis[j])*p[i]+q[i]\} ...
- 分治思想 特别常用 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 ...
- 快速排序基本思想,递归写法,python和java编写快速排序
1.基本思想 快速排序有很多种编写方法,递归和分递归,分而治之法属于非递归,比递归简单多了.在这不使用代码演示.下面我们来探讨一下快速排序的递归写法思想吧. 设要排序的数组是A[0]……A[N-1], ...
- 分治思想求解X的M次幂方
package main import ( "fmt" ) //递归形式分治求解 func power(x, m int) int { { } else { y := power( ...
随机推荐
- vector对象
vector是模板而非类型,由vector生成的类型必须包含vector中元素的类型,例如vector<int> 定义和初始化vector对象: vector<T> v1 ...
- HBase学习1(hbase基础)
认识NoSQL NoSQL:泛指非关系数据库(Not only SQL) NoSQL两重要特征:使用硬盘和把随机存储器作为存储载体 NoSQL分类(按照存储格式) 1)键值(Key-Value)存储数 ...
- java assert的使用并深入解析Java的assertion
java assert的使用并深入解析Java的assertion 分类: java2012-12-05 13:32 2020人阅读 评论(0) 收藏 举报 原文出处:http://blog.csdn ...
- dataframe to sql
使用pandas的to_sql时,还涉及到一些sql数据库的操作 在网上找到一段代码,很方便使用.来源:blog.csdn.net/qcyfred/article/details/78085243?l ...
- b树的实现(c++)
转自:http://blog.chinaunix.net/uid-20196318-id-3030529.html B树的定义 假设B树的度为t(t>=2),则B树满足如下要求:(参考算法导论) ...
- Android使用SVG小结
SVG的全称是Scalable Vector Graphics,叫可缩放矢量图形.它和位图(Bitmap)相对,SVG不会像位图一样因为缩放而让图片质量下降.它的优点在于节约空间,使用方便. andr ...
- addslashes及其反函数 stripslashes
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串. stripslashes() 去掉addslashes 所添加的反斜杠 预定义字符是: 单引号(') 双引号(") 反 ...
- 反射+type类+Assembly+特性
什么是元数据,什么是反射: 程序是用来处理数据的,文本和特性都是数据,而我们程序本身(类的定义和BLC中的类)这些也是数据. 有关程序及其类型的数据被称为元数据(metadata),它们保存在程序的程 ...
- 第一个DirectX程序include、lib设置问题
1.fatal error LNK1104: cannot open file "d3d9.lib" 解决方案: (1)项目 -->属性 --> 配置属性 --> ...
- 为mac编写swift脚本
代码示例: #!/usr/bin/env xcrun swift print("Hello World") 可以用Sublime Text编写,安装Swift包后有语法着色功能.然 ...