此算法借用快速排序算法。

这个快速选择算法主要利用递归调用,数组存储方式。包含3个文件,头文件QuickSelect.h,库函数QuickSelect.c,测试文件TestQuickSelect。

其中Cutoff可以自己给定,这个当开始给定的数组(或者递归调用产生的子数组)的元素个数<=20个时,采用插入排序。一般认为当元素个数<=20时,插入排序更快。这个20不是固定的,在这附近浮动都可以的。

头文件QuickSelect.h

 #ifndef QuickSelect_H
#define QuickSelect_H
#define Cutoff 20
typedef int ElementType;
ElementType Median3(ElementType A[], int left, int right);
void Swap(ElementType *p, ElementType*q);
void InsertionSort(ElementType A[], int N);
ElementType QuickSelect(ElementType A[],int k, int N);
ElementType Qselect(ElementType A[],int k, int Left, int Right);
void PrintMatrix(ElementType A[], int N);
#endif // !QuickSelect_H

库函数QuickSelect.c

 #include "QuickSelect.h"
#include<stdio.h>
//通过三数中值分割法获得数组的枢纽元
ElementType Median3(ElementType A[], int Left, int Right)
{
int Center = (Left + Right) / ;
if (A[Left] > A[Right])
Swap(&A[Left], &A[Right]);
if (A[Left] > A[Center])
Swap(&A[Left], &A[Center]);
if (A[Center] > A[Right])
Swap(&A[Center], &A[Right]);
//上述三次交换使得:A[Left]<A[Center]<A[Right]
Swap(&A[Center], &A[Right - ]);
return A[Right - ];//返回枢纽元;
} //交换指针p和q各自指向的值;
void Swap(ElementType * p, ElementType * q)
{
ElementType Tmp;
Tmp = *p;
*p = *q;
*q = Tmp;
} //当开始给定的数组(或者递归调用产生的子数组)的元素个数<=20个时,采用插入排序。
void InsertionSort(ElementType A[], int N)
{
int j, P;
ElementType Tmp;
for (P = ; P < N; P++)
{
Tmp = A[P];
for (j = P; j > && A[j - ] > Tmp; j--)
A[j] = A[j - ];
A[j] = Tmp;
}
} //快速选择算法驱动程序
ElementType QuickSelect(ElementType A[],int k, int N)
{
return Qselect(A, k-, , N - );//该程序即为,输入,k,返回A[k]。因为A从0开始存储,如果想找第5个最小值,其实找的是A[4],所以当我们找第k个值时,应输入k-1。
} //快速选择核心算法
ElementType Qselect(ElementType A[], int k, int Left, int Right)
{
int i, j;
ElementType Pivot;
if (Left + Cutoff - <= Right)//此处Cutoff-1是为了和N-1=Right对应上
{
Pivot = Median3(A, Left, Right);//调用枢纽元函数选取枢纽元
i = Left; j = Right - ;
for (; ;)
{
while (A[++i] < Pivot);
while (A[--j] > Pivot);
if (i < j) Swap(&A[i], &A[j]);
else break;
}
Swap(&A[i], &A[Right - ]);
if (k < i)
Qselect(A, k, Left, i - );//对剩下小于枢纽元的元素递归排序
else if (k>i)
Qselect(A, k, i + , Right);//对剩下大于枢纽元的元素递归排序
//当k=i时,即查询的值==枢纽元,则找到了,返回A[k]
}
else//当最后子数组只有Cutoff个,则采用插入排序。
InsertionSort(A + Left, Right - Left + );
return A[k];
} //打印数组
void PrintMatrix(ElementType A[], int N)
{
for (int i = ; i < N; i++)
printf("%d ", A[i]);
}

测试文件TestQuickSelect

 #include "QuickSelect.h"
#include <stdio.h>
#include<time.h>
#include<stdlib.h>
#define N 100000
int main()
{
ElementType A[N] ;
int ID;
srand((unsigned)time(NULL));
for (int i = ; i < N; i++)
{
//A[i] = rand() % N;
A[i] =N-i;//100000个数,倒序排
} printf("\n");
//PrintMatrix(A, N);
printf("请输入要查询的ID:");
scanf_s("%d", &ID);
printf("Result:%d",QuickSelect(A, ID, N));
printf("\n");
}

找到第k个最小元----快速选择的更多相关文章

  1. 在未排序的数组中找到第 k 个最大的元素

    在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 ...

  2. 【一起刷LeetCode】在未排序的数组中找到第 k 个最大的元素

    题目描述 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 ...

  3. 选取第K大数的快速选择算法和注意事项

    快速选择算法,是一种能在大致O(N)的时间内选取数组中第k大或者k小的算法.其基本思路与快速排序算法类似,也是分治的思想. 其实这个算法是个基础算法,但是不常用,所以今天编的时候错了POJ2388,才 ...

  4. [程序员代码面试指南]第9章-在两个长度相等的排序数组中找到第k小的数(二分)

    题目 给定两个有序数组arr1和arr2,再给定一个整数k,返回所有的数中第k小的数. 题解 利用题目"在两个长度相等的排序数组中找到第上中位数"的函数 分类讨论 k < 1 ...

  5. 比列的数目更多,以便找到第一k小值

    问题叙述性说明:现有n作为一个有序序列(2,3,9),(3,5,11,23),(1,4,7,9,15,17,20),(8,15,35,9),(20,30,40),第k小值. 问题分析:可用多路归并排序 ...

  6. 215. Kth Largest Element in an Array【Medium】【找到第 k 大的元素】

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  7. 算法总结之 在两个排序数组中找到第K小的数

    给定两个有序数组arr1 和 arr2 ,再给定一个int K,返回所有的数中第K小的数 要求长度如果分别为 N M,时间复杂度O(log(min{M,N}),额外空间复杂度O(1) 解决此题的方法跟 ...

  8. 【Leetcode 堆、快速选择、Top-K问题 BFPRT】有序矩阵中第K小的元素(378)

    题目 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素. 请注意,它是排序后的第k小元素,而不是第k个元素. 示例: matrix = [ [ 1, 5, 9], [ ...

  9. 【Leetcode 堆、快速选择、Top-K问题 BFPRT】数组中的第K个最大元素(215)

    这道题很强大,引出了很多知识点 题目 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5 ...

随机推荐

  1. Hangfire项目实践分享

    Hangfire项目实践分享 目录 Hangfire项目实践分享 目录 什么是Hangfire Hangfire基础 基于队列的任务处理(Fire-and-forget jobs) 延迟任务执行(De ...

  2. 【分享】标准springMVC+mybatis项目maven搭建最精简教程

    文章由来:公司有个实习同学需要做毕业设计,不会搭建环境,我就代劳了,顺便分享给刚入门的小伙伴,我是自学的JAVA,所以我懂的.... (大图直接观看显示很模糊,请在图片上点击右键然后在新窗口打开看) ...

  3. Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级

    Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 5.安装Database软件 5. ...

  4. macOS 我的装机

    最近多次配置 Mac 的开发环境,稍微记录一下 1 创建无付费信息的Apple ID 2 Xcode ​ gem 源更改 3 Alfred 4 微信 5 SourceTree 6 Sublime Te ...

  5. salesforce 零基础学习(六十二)获取sObject中类型为Picklist的field values(含record type)

    本篇引用以下三个链接: http://www.tgerm.com/2012/01/recordtype-specific-picklist-values.html?m=1 https://github ...

  6. HTML 事件(三) 事件流与事件委托

    本篇主要介绍HTML DOM中的事件流和事件委托. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4 ...

  7. Golang 编写的图片压缩程序,质量、尺寸压缩,批量、单张压缩

    目录: 前序 效果图 简介 全部代码 前序: 接触 golang 不久,一直是边学边做,边总结,深深感到这门语言的魅力,等下要跟大家分享是最近项目 服务端 用到的图片压缩程序,我单独分离了出来,做成了 ...

  8. Javascript 严格模式详解

    转自http://www.ruanyifeng.com/blog/2013/01/javascript_strict_mode.html 一.概述 除了正常运行模式,ECMAscript 5添加了第二 ...

  9. 分享两个BPM配置小技巧

    1.小技巧 流程图修改后发布的话版本号会+1,修改次数多了之后可能会导致版本号很高,这个时候可以将流程导出,然后删除对应的流程包再导入,发布数据模型和流程图之后,版本清零 2.小技巧 有的同事入职后使 ...

  10. C语言可以开发哪些项目?

    C语言是我们大多数人的编程入门语言,对其也再熟悉不过了,不过很多初学者在学习的过程中难免会出现迷茫,比如:不知道C语言可以开发哪些项目,可以应用在哪些实际的开发中--,这些迷茫也导致了我们在学习的过程 ...