快速排序+快速定位

快速排序算法采用了分治法以及递归作为解决问题的思想。在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。

快速排序算法

算法思路

快速排序算法的思路是,先在arr[s,t]中随意选取一个点作为排序的基准点x,再确定基准点在数组中的下标,一定下标i确定后,该下标i左边的所有元素均小于x,右边的所有元素均大于x.此时采用递归继续对数组[s,i-1]以及[i+1,t]做快速排序,左右区间不再合法即可退出循环。分治的思想就体现在同时对基准点的左右区间再次做快速排序上。

找基准点

首先,姑且认为区间左端的第一个元素就是基准点x,再定义两个下标i与j分别记录区间的原始左端点与右端点,先从右端点开始往左查找如果arr[j]>=x且i<j,则j--,这样能够确保基准点右边的元素都大于或等于基准点若遇到arr[j]<x,则将arr[j]放到基准点原来的位置;紧接着下标i往右查找,如果arr[i]<=x且i<j,则i++,这样能够保障基准点左边的元素都小于或等于基准点;若遇到arr[i]>x,则将arr[i]放到上次j的位置;重复上述操作,直到i==j,将基准点放在arr[i]上,即arr[i]=x.

代码实现

#include<iostream>
using namespace std;
#include<algorithm>

//快速查找算法,查找第k小的元素

void quick_sort(int*arr,int l,int r){
    //递归退出条件
    if(l>=r){
        return ;
    }
    int i = l;
    int j = r;
    //以区间最左侧的元素最为基准点
    int x = arr[l];
    
    //调整基准点
    while(i<j){
        //找到一个比基准点小的数
        while(i<j && arr[j]>=x)  j--;
        if(i<j){
            //将arr[j]放到最左边
            arr[i] = arr[j];
        } 
        //找一个比基准点大的数
        while(i<j && arr[i]<=x)     i++;
        if(i<j){
            arr[j] = arr[i];
        }
    }    
    arr[i] = x;
    //调整基准点
    //对基准点的左区间排序
    quick_sort(arr,l,i-1);
    //对基准点的右区间排序
    quick_sort(arr,i+1,r);
}
void Myprint(int val){
    cout<<val<<" ";
}

int main(){
    int arr[12]={10,2,1,3,6,5,4,7,9,8,42,99};
    int len = sizeof(arr)/sizeof(int);
    quick_sort(arr,0,len-1);
    for_each(arr,arr+len,Myprint);
    cout<<endl;
    return 0;
}

快速定位算法

问题引入

已知定长为len的int数组,需要查出第k小的元素。

算法思路

借鉴快速排序的思路,基准点必定大于或等于其左区间的元素小于或等于右区间的元素,因此找到一个下标为k-1的基准点等价于找到第k小的元素。我们只需要在原快速排序算法删改一些代码即可获得快速排序算法的代码实现。

代码实现

#include<iostream>
using namespace std;

//快速查找算法,查找第k小的元素

int quick_select(int*arr,int l,int r, int k){
    int i = l;
    int j = r;
    //以区间左端点为基准点
    int x = arr[l];
    //调整基准点
    while(i<j){
        //找到一个比基准点小的数
        while(i<j && arr[j]>=x)  j--;
        if(i<j){
            //将arr[j]放到最左边
            arr[i] = arr[j];
        } 
        //找一个比基准点大的数
        while(i<j && arr[i]<=x)     i++;
        if(i<j){
            arr[j] = arr[i];
        }
    }    
    arr[i] = x;
    //调整基准点
    //判断基准点x的下标i是否与k-1相同
    if(i==k-1) 
        return arr[i];
    else if(i<k-1)
        return quick_select(arr,i+1,r,k);
    else
        return quick_select(arr,l,i-1,k);
}

int main(){
    int arr[12]={10,2,1,3,6,5,4,7,9,8,42,99};
    int k  = 12;
    int len = sizeof(arr)/sizeof(int);
    cout<<quick_select(arr,0,len-1,k)<<endl;
    //答案无疑是99
    return 0;
}

可见,当i<k-1时,说明第k小的元素在基准点的右侧,只需要再查找基准点的右侧区间;当i>k-1时,说明第k小的元素在基准点的左侧,只需要再查找基准点的左侧区间

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
多关键字排序是一种根据多个关键字来对数据进行排序的算法。术语中的3C代表的是Computing(计算)、Communications(通信)和Consumer electronics(消费电子)三个领域,这三个领域在现代社会中发挥着巨大作用。 在计算领域,多关键字排序可以用来对数据进行优化。常见的排序算法包括冒泡排序、插入排序、选择排序快速排序、归并排序等。但是在处理一些大规模数据时,单关键字排序的效率会变得较低。因此,多关键字排序在解决这类问题时具有很大的优势。例如,在一个巨大的数据库中,需要快速找到一组符合特定条件的数据,这时多关键字排序可以对数据进行精准的排序,同时也能够快速定位目标数据。 在通信领域,多关键字排序可以得到广泛应用。例如,如果需要对网络流量进行排序,单关键字排序不能够满足需求。因为网络流量除了大小之外,还具有来源IP地址、目标IP地址、协议类型、时间戳等多个属性,需要根据多个关键字进行排序。多关键字排序可以避免网络堵塞和数据丢失的现象,提高网络通信效率和质量。 在消费电子领域,多关键字排序的应用则更加广泛。例如,在智能手机中可以根据多个条件来对联系人进行排序,例如常用等级、姓名首字母、姓氏等等。这样用户可以更加方便地浏览和管理自己的联系人。在智能家居中,也可以根据多个条件对设备进行排序,例如房间、功能、品牌等等。这样用户可以更加方便地控制和管理家里的设备。 总之,多关键字排序在计算、通信和消费电子等领域都具有举足轻重的重要性,对提高计算效率、改进通信质量、提高用户体验都具有很大的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值