1. 程式人生 > >陣列中查詢第k小元素的複雜度為O(n)的演算法

陣列中查詢第k小元素的複雜度為O(n)的演算法

import java.util.Random;
public class hello{
public static int []aa;

public static void main(String args[])
{
int []b=new int[11];
//int []b={8,4,7,8,6,5,10,8,6,10,8};
int l=0,k=5;
Random rand=new Random();
for(int i=0;i<b.length;++i){
b[i]=rand.nextInt(b.length);
System.out.println(b[i]);
}
aa=b;
//int result1=q_search_rec(l,aa.length-1,k-1);  //陣列下標和實際序號差1
//System.out.println("遞迴呼叫的:第"+k+"小的數是");
//System.out.println(aa[result1]);
int result2=q_search_ite_ditto(l,aa.length-1,k-1);
System.out.println("迴圈迭代的:第"+k+"小的數是");
System.out.println(aa[result2]);

}

查詢陣列序列中的第k小元素的程式碼如下,框架類似於quick_sort(),區別是其只對包含第k小元素的那一側進行運算,所以複雜度只有O(n)。  

//遞迴快速查詢方法  
static int q_search_rec(int l,int n,int k)
{
Random rand=new Random();
int t=rand.nextInt(n-l+1)+l;
swap(l,t);
int m,i;
m=l;
for(i=l+1;i<=n;++i)
{
if(aa[i]<aa[l])
{
swap(++m,i);
}
}
swap(l,m);
if(m==k)
return m;
else if(m<k)
return q_search_rec(m+1,n,k);
else
return q_search_rec(l,m-1,k);
}

public static void swap(int a,int b)     //交換下標為a,b的元素
{  
int c;
c=aa[a];
aa[a]=aa[b];
aa[b]=c;
}

//下面是迭代演算法。注意迭代演算法部分,while迴圈條件是low

<=high,而不是“<”。原因是:當執行過程中low==k,而high=m=k+1時,此時執行到if條件句時,high=m-//1=low;函式會返回-1報錯。

static int q_search_ite(int l,int n,int k){
int m,i,low =l,high=n;
Random rand =new Random();
while(low<=high){
int t=rand.nextInt(high-low+1)+low;
swap(low,t);
m=low;
for(i=low+1;i<=high;++i)
{
if(aa[i]<aa[low])
swap(++m,i);
}
swap(m,low);
if(m==k)
return m;
else if(m<k){
low=m+1;
//System.out.println("low值:"+low);
}
else{
high=m-1;
//System.out.println("high值:"+high);
}
}
return -1;
}

//有大量相同元素,改進演算法效率的方案 即增加q,low~m的小於t,m~q的等於t,q~high的大於t
static int q_search_ite_ditto(int l,int n,int k){
int low,high,m,t,q,xx;
low=l;high=n;
Random rand=new Random();
while(low<=high)
{
t=rand.nextInt(high-low+1)+low;
swap(t,low);
m=low;q=low;
for(int i=low+1;i<=high;++i)
{
if(aa[i]<aa[low])
{
swap(++q,i);
swap(++m,q);
System.out.println("");
}
else if(aa[i]==aa[low])
{
swap(++q,i);
}
}
swap(low,m);
if(k>=m&&k<=q)
{

for(xx=m;xx<=q;xx++)
System.out.println("m~q之間的值:"+aa[xx]);
return m;
}
else if(m>k)
{
high=m-1;
//System.out.println("high值:"+high);
}
else
{
low=q+1;
//System.out.println("low值:"+low);
}
}
return -1;
}
}

相關推薦

陣列查詢k元素複雜O(n)的演算法

import java.util.Random; public class hello{public static int []aa;public static void main(String args[]){int []b=new int[11]; //int []b=

陣列2——查詢k元素

在陣列a的前n個元素中找出第k(1≤k≤n)小的元素,例如,陣列{98, 33, 21, 102, 45, 5, 32, 11, 65, 82, 193, 321, 34, 72}中第5小的元素是33。 【分析】 這是上海大學考研試題。要查詢第k小的元素,並不需要完全對陣列中的元素進行排序,

陣列找到k元素

#include <stdio.h> #include <stdlib.h> int Element_k( int data[] , int key ,int low , int high ){ //基於快排的思想,如果pivot=data[low], low=k

尋找陣列k的數:平均情況下時間複雜O(n)的快速選擇演算法

又叫線性選擇演算法,這是一種平均情況下時間複雜度為O(n)的快速選擇演算法,用到的是快速排序中的第一步,將第一個數作為中樞,使大於它的所有數放到它右邊,小於它的所有數放到它左邊。之後比較該中樞的最後位

[牛客算法系列] 在另個排序陣列找到k的數

題目 給定兩個有序陣列arr1,arr2, 再給定一個整數k, 返回所有數中第k 小的數。 比如 arr1 = [1,2,3,4,5], arr2 = [3,4,5], k =1. 1 是所有數中第

隨機快排查詢k元素和隨機化查詢k元素

隨機化查詢第k小元素:不必將所有元素按從大到小或從小到大排序即可找出第k小值 思路:隨機從序列中取一值,從第一個值開始,將比起小的放在左面,比起大的放在右面。然後比較k與這個值的位置(陣列下角標,我設定成從1開始的)如果k的值比這個值的下角標大,那麼取這個值的右半部分(都比這個值小)然後再從其中

9.27 在兩個排序陣列找到K的數

【題目】:   給定兩個有序陣列arr1和arr2,再給定一個整數k,返回所有的數中第K小的數   舉例:     arr1=[1, 2, 3, 4, 5],arr2=[3, 4, 5],k=1     1是所有數中第1小的數,所以返回1     arr1=[1, 2, 3],arr2=[3, 4,

查詢K元素(C語言版)

       今天在看《演算法:C語言實現》時,在快速排序那一章最後一節講述了利用快速排序的思想,快速排序每次劃分後在樞軸的左邊的元素都比樞軸小(或相等),在樞軸右邊的數都比樞軸大(或相等),而劃分後樞軸本身就放在了(有序時)它自身應該在的位置,在每次劃分後判斷樞軸下標和k

【C++實現】k元素 時間複雜O(n),空間複雜O(1)

解題思路: 二基準快速排序,在排序時判斷每次找到的標記點下標 p 與 n-k 的大小,若小於n-k,則只需在p的右側繼續遞迴,若大於 p 則只需在p 的左側遞迴,直至 p 與 n-k 相等 vs可執行程式碼 #include<ctime> #includ

把一個含有N元素陣列迴圈右移K位, 要求時間複雜O(N)

分析與解法 這個解法其實在《啊哈!演算法》有講到。 假設原陣列序列為abcd1234,要求變換成的陣列序列為1234abcd,即迴圈右移了4位,比較之後,不難看出,其中有兩段的順序是不變的:1234和abcd,可把兩段看成兩個整體。右移K位的過程就是把陣列的兩部分交換一下。

解決尋找K元素問題——三種不同的演算法實現

問題描述:在一個序列裡找出第K小元素 以下程式基於函式 int select_kth_smallest(list q, int k) 實現 :返回向量q中第k最小元的函式 演算法一: 基於氣泡排序思想,暴力求解: 基本思路:要求找出第k個最小元素,可以通過在序

把一個含有N元素陣列迴圈右移K位,要求時間複雜O(N)

分析與解法 假設原陣列序列為abcd1234,要求變換成的陣列序列為1234abcd,即迴圈右移了4位,比較之後,不難看出,其中有兩段的順序是不變的:1234和abcd,可把兩段看成兩個整體。右移K位的過程就是把陣列的兩部分交換一下。變換過程通過以下步驟完成: 1.逆序排列

長度n的順序表L,編寫一個時間複雜O(n),空間複雜O(1)的演算法,該演算法刪除線性表所有值X的元素

解法:用K記錄順序表L中不等於X的元素個數,邊掃描L邊統計K,並將不等於X的元素向前放置K位置上,最後修改L長度 void  del_x_1(SqList &L,Elemtype x){ int k=0; for(i=0;i<L.length;i++) {

陣列排序,陣列所有的負整數出現在正整數前面(時間複雜 O(n), 空間複雜 O(1)).

<pre name="code" class="plain">#include <stdio.h> #define N 10 void swap (int *a, int i,

刪除線性表所有值x的元素,要求時間複雜O(n),空間複雜O(1)

思路:統計不等於x的個數,用k記錄不等於x的元素的個數。邊統計邊把當前元素放在第k個位置上,最後修改表的長度 public static void del(List<Integer> l

在一個含有空格字元的字串加入XXX,演算法時間複雜O(N)

import java.util.Scanner; /** * */ /** * @author jueying: * @version 建立時間:2018-10-18 下午10:54:54 * 類說明 */ /** * @author jueying

有一個整形陣列A,請設計一個複雜O(n)的演算法,算出排序後相鄰兩數的最大差值。

有一個整型陣列,請設計一個複雜度為O(n)的演算法,算出排序後相鄰兩數的最大差值。 Given an unsorted array, find the maximum difference betwe

複雜O(n)的取一組數分佈最密集的部分的演算法

    公司有一個檢測系統,在單位時間內將每次檢測結果儲存。由於檢測的環境受到外界干擾,會隨機地出現異常值。以前的辦法是:取得所有檢測結果的最大值作為最終值。由於異常值的出現,導致檢測結果非常不準確。於是思考在整個檢測結

有1,2,....一直到n的無序陣列,求排序演算法,要求時間複雜O(n),空間複雜O(1)

http://blog.csdn.net/dazhong159/article/details/7921527 1、有1,2,....一直到n的無序陣列,求排序演算法,並且要求時間複雜度為O(n),空間複雜度O(1),使用交換,而且一次只能交換兩個數。 #include &

4章 貪心演算法,Dijkstra演算法(鄰接矩陣儲存,時間複雜O(n^2))

#include <iostream> #include <cstdio> #include <cstring> using namespace std; #d