利用堆排序得到前K小元素

2021-06-29 15:09:32 字數 2239 閱讀 8903

問題描述:在n個數中找到前k小的數(不是第k小),其中n>>k(n遠大於k),並且n個數是逐漸生成的。

由於n取值很大,所以不可能把n個值全部儲存下來後再通過排序的方法解決,這樣做缺點有:

1、需要分配大量記憶體來儲存這n個數

2、只需要找到前k小,其它n-k個數沒必要儲存

3、假如有很多組這樣的n個數都需要找到前k小的數,則肯定會導致記憶體溢位

所以把n個值全部儲存下來後再通過排序的方法解決的思路不可取。

這裡借鑑堆排序(堆排序詳見的方法,對每組生成的n個數找前k小只需要申請有k個儲存單元的陣列arr,把n個數中的前k個數用來填充陣列arr,當arr被填滿時執行一次堆排序(這裡利用的是小根堆),堆排序結束後arr下標為0的位置存放的是這k個數中的最大值,接下來把生成的k+1到第n個數分別於arr[0]作比較,當且僅當新生成的數字小於arr[0]時,用這個新生成的數字替換掉arr[0],並重新執行一次堆排序,迴圈反覆,最終就可以找到n個數的前k小。

完整**如下:

package test;

public class test ;

system.out.print("排序前:");

for(int tmp : target)

//開始堆排序

heap_sort(target, target.length);

//測試搜尋前10小

int test = new int;

for(int i = 0; i < 10; i++)

} system.out.println();

system.out.print("前k小值:");

for(int tmp : target)

} public static void heap_sort(int arr, int arr_length)

//debug

system.out.println();

system.out.print("建堆後:");

for(int tmp : arr)

system.out.println();

system.out.print("最大值:" + max + " 下標值:" + index);

//n-1 times sx

for(int j = arr_length - 1; j >= 0; j--)

} //篩選演算法

public static void sx(int arr, int parent, int end)

}else

}}else

}if(arr[parent] > arr[min_sub_index])

swap(arr, parent, min_sub_index);

parent = min_sub_index;

left_sub = 2 * parent + 1;

right_sub = 2 * parent + 2;

}else

} }public static void swap(int arr, int src, int destinate)

}

執行結果:

排序前:11  12  13  14  -1  -2  -3  -4  20  8  

建堆後:-4 -1 -3 12 8 -2 13 14 20 11

最大值:20 下標值:8

建堆後:-4 -3 -1 -2 11 8 13 0 12 14

最大值:20 下標值:8

建堆後:-4 -3 -1 -2 8 0 12 1 11 13

最大值:20 下標值:8

建堆後:-4 -3 -1 -2 1 0 11 2 8 12

最大值:20 下標值:8

建堆後:-4 -3 -1 -2 1 0 8 3 2 11

最大值:20 下標值:8

建堆後:-4 -3 -1 -2 1 0 3 4 2 8

最大值:20 下標值:8

建堆後:-4 -3 -1 -2 1 0 3 5 2 4

最大值:20 下標值:8

前k小值:5 4 3 2 1 0 -1 -2 -3 -4

ps:在**中加了求最大值及其下標的**,和解決本問題沒有關係,純粹是開發時除錯使用,使用時請根據個人情況刪除。

最小的k個數 第k小的數(利用快排,堆排序)

快排 若求top m個元素,則只需把下面的程式裡的k換乘n m即可 利用快排求最小的k個數,第k小的數 void getleastknum int input,int n,int output,int k else for int i 0 i 其中,output k 1 就是第k小的數 partit...

出現次數前k多的元素 桶排序

347.前 k 個高頻元素 給定乙個非空的整數陣列,返回其 現頻率前 k 高的元素。示例 1 輸入 nums 1,1,1,2,2,3 k 2 輸出 1,2 示例 2 輸入 nums 1 k 1 輸出 1 你可以假設給定的 k 總是合理的,且 1 k 陣列中不相同的元素的個數。你的演算法的時間複雜度必...

排序 最小堆 347 前 K 個高頻元素

給定乙個非空的整數陣列,返回其 現頻率前 k 高的元素。示例 1 輸入 nums 1 1,1 2,2 3 k 2輸出 1 2 示例 2 輸入 nums 1 k 1輸出 1 你可以假設給定的 k 總是合理的,且 1 k 陣列中不相同的元素的個數。你的演算法的時間複雜度必須優於 o n log n n ...