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

快速排序算法是基于分治策略的另一个排序算法。它的基本思想是、:
(1)分解(divide):以数组a[p,r ]中的某一个数a[q]将数组分成三部分:a[1...q-1] a[q] a[q+1...r]。其中a[1...q-1]中的任何一个数都比a[q]小,而a[q+1...r]中的任何一个数都比a[q[]大。下标q在划分过程中确定。

(2) 递归求解(conquer):通过递归调用快速排序算法分别对a[1...q-1]和a[q+1...r]进行排序。

(3) 合并(merge):由于a[1...q-1]和a[q+1...r]的排序是就地进行的,即不需要花费额外的存储空间,即排序好后的结果仍然在a[ ]中。

快速排序的运行时间和每一次的划分是否对称有关,即每次划分所取的q都恰好为中值,即每一次的划分都产生两个大小为n/2的区域,此时,partition的时间复杂度为O(nlogn)。关于几种排序的时间复杂度怎么计算,将在另一篇博客中介绍。

不难想到,快速排序的最坏情况是每一次的划分,产生的是一个长度为1的数组以及一个长度为n-1的数组,这时,类似于冒泡排序,时间复杂度将为n^2。容易看到,快速排序的性能取决于划分的是对称性,通过修改partition函数,可以设计出采用随机选择策略的快速排序算法,当数组还没有被划分之前,可以在a[p,r]中随机选出一个元素作为基准,这样可以使得划分基准的选择是随机的,从而使得从概率上来讲,假设数组很大,则整体上来讲划分是比较对称的。

如何随机得到【a, b】内的整数?(包含a, b):

#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;

int main()
{
    int a=0,b=11;
    srand((unsigned)time(NULL));
    for(int i = 0; i < 10;i++ )
        cout << (rand() % (b-a+1))+ a << '\t';
    cout << endl;
return 0;
}
全部代码:
#include<iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;


int Random(int left, int right)              //随机函数生成[left, righth]之间的一个整数
{
    srand((unsigned)time(NULL));
    int r = (rand() % (right-left+1))+ left;
    return r;
}
int Partition(int a[], int left, int right)
{
    int x = a[right];        //将输入数组的第rand个元素作为基准元,用它来对数组进行划分
    int i = left - 1;        //i为最后一个小于基准元的数的下标
    for (int j = left; j < right; j++)//遍历下标由left到right-1的数
    {
        if (a[j] < x)//如果数小于基准元的话就将i向前挪动一个位置,并且交换j和i所分别指向的数
        {
            int temp;
            i++;
            temp = a[i];
            a[i] = a[j];
            a[j] = temp;
        }
    }
//经历上面的循环之后下标为从left到i(包括i)的数就均为小于x的数了,现在将主元和i+1位置上面的数进行交换
    a[right] = a[i + 1];
    a[i + 1] = x;
    return i + 1;
}
//经历上面的之后下标为从left到i(包括i)的数就均为小于x的数了,而i+2到right的数则均不小于x
int RandommizedPartition(int a[], int p, int r)
{        
    int i = Random(p, r);        
    int temp = a[p];        
    a[p]=a[i];        
    a[i]=temp;       
    return Partition(a,p,r);
}
void RandommizedQuickSort(int a[], int left, int right)
{        
    if (left < right)        
    {                
        int q = RandommizedPartition(a, left, right);                
        RandommizedQuickSort(a, left, q - 1);                
        RandommizedQuickSort(a, q + 1, right);        
    }
}
int main()
{        
    int a[12];       
    int i, j, n;        
    cout<<"输入元素个数n:"<<endl;        
    cin>>n;        
    cout<<"输入n个元素:"<<endl;        
    for(i=0;i<n;i++)               
        cin>>a[i];        
    RandommizedQuickSort(a,0,n-1);       
    for(i=0;i<n;i++)                
        cout<<a[i]<<" ";        
    cout<<endl;        
    return 0;
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值