博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
分治算法--寻找第k大数
阅读量:6457 次
发布时间:2019-06-23

本文共 2619 字,大约阅读时间需要 8 分钟。

  问题描述:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k大的元素,(这里给定的线性集是无序的)。

  其实这个问题很简单,直接对线性序列集qsort,再找出第k个即可。但是这样的时间复杂度就是qsort的时间复杂度O(nlogn)。有没有更快的方法呢?看到网上有一种解法是采取了快排的思路,但是稍微坐了些改动,然后时间复杂度能够接近O(n)。因为最近刚刚写了快排的实现,所以在这我就再把这个实现一次吧。

  解题思路:与快排不同的是,这里只对划分出来的其中一组进行递归处理。任意选定一个pivotIndex,pivotValue = arr[pivotIndex]。经过一次划分后,pivotValue存储在storeIndex的位置,storeIndex把数组划分为两部分。比pivoteValue大的在前面,比pivotValue小的存储在后面(此时前后两部分是没有排好序的)。那么storeIndex位置的pivotValue就肯定是第storeIndex大的数。然后用K于storeIndex比较,如果K<storeIndex,那么说明第K大一定在右边,那么再对右边进行划分即可。如果K>storeIndex,那么说明第K大一定在左边,那么再对左边进行划分。然后递归,最后就可以得到第K大。

#include 
void swap(int *a, int *b){ int tmp; tmp = *a; *a = *b; *b = tmp;}int partition(int arr[], int left, int right, int pivotIndex){ int storeIndex = left; int pivotValue = arr[pivotIndex]; int i; swap(&arr[pivotIndex],&arr[right]); for (i = left; i < right; i ++) { if (arr[i] > pivotValue) { swap(&arr[i],&arr[storeIndex]); storeIndex++; } } swap(&arr[storeIndex],&arr[right]); return storeIndex;}int findKMax(int arr[], int left, int right, int k){ int nRet; int pivotIndex = left + 1; nRet = partition(arr,left,right,pivotIndex); if (nRet < k) { return findKMax(arr,nRet+1,right,k); } else if (nRet > k) { return findKMax(arr,left,nRet-1,k); } return nRet;}int main(){ int i,k,nRet; int arr[] = {
8,3,4,1,9,7,6,10}; scanf("%d",&k); nRet = findKMax(arr,0,7,k-1); printf("The Kth Max Number locate in %d is :%d\n",nRet,arr[nRet]); for (i = 0; i < 8; i++) { printf("%3d",arr[i]); } return 0;} 2013/6/17 19:55

 

  列出了很多种寻找第K大数的算法。

第二次实现该算法:

#include 
void swap(int arr[], int i, int j){ int tmp; tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;}int partition(int arr[], int left, int right){ int value = arr[left]; int p_insert,p_cmp; swap(arr,left,right); p_insert = p_cmp = left; while (p_cmp < right) { if (arr[p_cmp] < value) { swap(arr,p_insert,p_cmp); p_insert++; } p_cmp++; } swap(arr,p_insert,right); return p_insert;}void max_k(int arr[], int left, int right,int k){ int ret = partition(arr,left,right); if (ret == k) return; else if (ret < k) ret = partition(arr,ret+1,right); else ret = partition(arr,left,ret); }int main(){ int arr[] = {
9,10,7,8,3,12,15,76,6}; int i,k = 5; max_k(arr,0,8,k); for (i = 0; i < k; i++) { printf("%d ",arr[i]); } printf("\n"); return 0;}2013/10/21 22:42

转载地址:http://qrnzo.baihongyu.com/

你可能感兴趣的文章
慕课网学习手记--炫丽的倒计时效果Canvas绘图与动画基础
查看>>
==与equals()的区别
查看>>
TCP三次握手四次挥手相关问题探讨
查看>>
基本分类方法——KNN(K近邻)算法
查看>>
在XenCenter6.2中构建CentOS7虚拟机的启动错误
查看>>
.NET Framework3.0/3.5/4.0/4.5新增功能摘要
查看>>
php中表单提交复选框与下拉列表项
查看>>
熟悉常用的Linux操作
查看>>
WordPress 前端投稿/编辑发表文章插件 DJD Site Post(支持游客和已注册用户)汉化版 免费下载...
查看>>
C# 自定义事件整理项目 - EventDemo
查看>>
几何面积体积_2
查看>>
面象过程与面象对象
查看>>
用CSS实现图片水印效果代码
查看>>
谷歌设置支持webgl
查看>>
P3402 【模板】可持久化并查集
查看>>
js的AJAX请求有关知识总结
查看>>
Eclipse添加新server时无法选择Tomcat7的问题
查看>>
L207
查看>>
nginx 配置https 负载均衡
查看>>
listing_windows形式输出直线结构体的起点、终点信息
查看>>