找到第k个最小元----快速选择
此算法借用快速排序算法。
这个快速选择算法主要利用递归调用,数组存储方式。包含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个最小元----快速选择的更多相关文章
- 在未排序的数组中找到第 k 个最大的元素
在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 ...
- 【一起刷LeetCode】在未排序的数组中找到第 k 个最大的元素
题目描述 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 ...
- 选取第K大数的快速选择算法和注意事项
快速选择算法,是一种能在大致O(N)的时间内选取数组中第k大或者k小的算法.其基本思路与快速排序算法类似,也是分治的思想. 其实这个算法是个基础算法,但是不常用,所以今天编的时候错了POJ2388,才 ...
- [程序员代码面试指南]第9章-在两个长度相等的排序数组中找到第k小的数(二分)
题目 给定两个有序数组arr1和arr2,再给定一个整数k,返回所有的数中第k小的数. 题解 利用题目"在两个长度相等的排序数组中找到第上中位数"的函数 分类讨论 k < 1 ...
- 比列的数目更多,以便找到第一k小值
问题叙述性说明:现有n作为一个有序序列(2,3,9),(3,5,11,23),(1,4,7,9,15,17,20),(8,15,35,9),(20,30,40),第k小值. 问题分析:可用多路归并排序 ...
- 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 ...
- 算法总结之 在两个排序数组中找到第K小的数
给定两个有序数组arr1 和 arr2 ,再给定一个int K,返回所有的数中第K小的数 要求长度如果分别为 N M,时间复杂度O(log(min{M,N}),额外空间复杂度O(1) 解决此题的方法跟 ...
- 【Leetcode 堆、快速选择、Top-K问题 BFPRT】有序矩阵中第K小的元素(378)
题目 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素. 请注意,它是排序后的第k小元素,而不是第k个元素. 示例: matrix = [ [ 1, 5, 9], [ ...
- 【Leetcode 堆、快速选择、Top-K问题 BFPRT】数组中的第K个最大元素(215)
这道题很强大,引出了很多知识点 题目 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5 ...
随机推荐
- Ubuntu下使用nvm
写在前面:刚写着写着博客就跨年了,希望新的一年大家万事如意,一切向"前"看! 安装 wget -qO- https://raw.githubusercontent.com/crea ...
- ASP.NET Aries 入门开发教程9:业务表单的开发
前言: 经过前面那么多篇的列表的介绍,终于到了大伙期待的表单开发了. 也是本系列的最后一篇文章了! 1:表单页面的权限设置与继承 对于表单页面,权限的设置有两种: 1:你可以选择添加菜单(设置为不显示 ...
- 如何在nuget上传自己的包+搭建自己公司的NuGet服务器(新方法)
运维相关:http://www.cnblogs.com/dunitian/p/4822808.html#iis 先注册一个nuget账号https://www.nuget.org/ 下载并安装一下Nu ...
- python爬取github数据
爬虫流程 在上周写完用scrapy爬去知乎用户信息的爬虫之后,github上star个数一下就在公司小组内部排的上名次了,我还信誓旦旦的跟上级吹牛皮说如果再写一个,都不好意思和你再提star了,怕你们 ...
- 个人网站对xss跨站脚本攻击(重点是富文本编辑器情况)和sql注入攻击的防范
昨天本博客受到了xss跨站脚本注入攻击,3分钟攻陷--其实攻击者进攻的手法很简单,没啥技术含量.只能感叹自己之前竟然完全没防范. 这是数据库里留下的一些记录.最后那人弄了一个无限循环弹出框的脚本,估计 ...
- 小兔JS教程(三)-- 彻底攻略JS回调函数
这一讲来谈谈回调函数. 其实一句话就能概括这个东西: 回调函数就是把一个函数当做参数,传入另一个函数中.传进去的目的仅仅是为了在某个时刻去执行它. 如果不执行,那么你传一个函数进去干嘛呢? 就比如说对 ...
- spring无法读取properties文件数据
只讲述异常点,关于怎么配置文件,这里不做说明. 1. controller中无法读取config.properties文件 controller中注入的@Value配置是从servlet-cont ...
- 易用BPM时代,软件开发者缘何选择H3?
近年来,企业级软件开发市场暗流汹涌,呈现出多种态势.软件开发团队规模趋于小型化,工作方式趋于快捷化,超过半数的软件开发者在工作中会选择使用易用的软件开发工具.随着流程管理越来越受到企业的重视,流程开发 ...
- 2016年中国微信小程序专题研究报告
2016年12月29日,全球领先的移动互联网第三方数据挖掘和分析机构iiMedia Research(艾媒咨询)权威首发<2016年中国微信小程序专题研究报告>. 报告显示,82.6%手机 ...
- excel常用技巧
复制表格时,如果要加上行标和列标.页面布局->工作表选项:标题,勾上打印->复制下拉框->复制为图片加上打印样式 一行长拆成几行短或几行短变成一行长的文本拆分,可以通过:填充-> ...