從無序陣列中找出第K大的數

2022-08-24 05:33:08 字數 1658 閱讀 6044

該題目的兩種實現方式,第一種是用堆排序(其中陣列用到了二叉樹的性質),第二種是利用快速排序來實現.

最大堆進行公升序排序,主要步驟是

1.初始化堆:將數列a[1...n]構造成最大堆。

2.交換資料:將a[1]和a[n]交換,使a[n]是a[1...n]中的最大值;然後將a[1...n-1]重新調整為最大堆。 接著,將a[1]和a[n-1]交換,使a[n-1]是a[1...n-1]中的最大值;然後將a[1...n-2]重新調整為最大值。 依次類推,直到整個數列都是有序的。

1

static

void swap(ref t t1, ref

t t2) 67

static

void maxheap_down(int arr, int start, int

end)

17if (temp >=arr[left])

18break;19

else23}

24}2526

static

int heap_find_numberk(int arr, int

k) 33

34for (i = n - 1; i >= k-1; i--)

38return arr[k - 1

];39 }

堆排序時間複雜度

堆排序的時間複雜度是o(n*lgn)。

假設被排序的數列中有n個數。遍歷一趟的時間複雜度是o(n),需要遍歷多少次呢?

堆排序是採用的二叉堆進行排序的,二叉堆就是一棵二叉樹,它需要遍歷的次數就是二叉樹的深度,而根據完全二叉樹的定義,它的深度至少是lg(n+1)。最多是多少呢?由於二叉堆是完全二叉樹,因此,它的深度最多也不會超過lg(2n)。因此,遍歷一趟的時間複雜度是o(n),而遍歷次數介於lg(n+1)和lg(2n)之間;因此得出它的時間複雜度是o(n*lgn)。

利用快排劃分出來的主元位置再遞迴尋找,這種方法叫作隨機選擇演算法。它對任何輸入都可以達到o(n

)'>o(n)的期望時間複雜度。

1

static

int randpartition(int arr, int left, int

right)

8 arr[left] =arr[right];

9while (left < right && arr[left] <= temp)

10 arr[right] =arr[left];11}

12 arr[left] =temp;

13return

left;14}

1516

static

int randselect(int arr, int left, int right, int

k) 20

int index =randpartition(arr, left, right);

21int m = index + 1;22

if (m ==k)

25int result = -1;26

if (m 29else

if (m >k)

32return

result;

33 }

從n個無序數中找出第K大的數

n個無序數中求第k大數 include include include using namespace std 氣泡排序思想,時間複雜度 o n k int findk 2 int a,int k return a k 1 堆排序思想,時間複雜度 o nlogk 將a s.m 調正為堆,其中除s位置...

演算法導論 快速找出無序陣列中第k小的數

題目描述 給定乙個無序整數陣列,返回這個陣列中第k小的數。解析 最平常的思路是將陣列排序,最快的排序是快排,然後返回已排序陣列的第k個數,演算法時間複雜度為o nlogn 空間複雜度為o 1 使用快排的思想,但是每次只對patition之後的陣列的一半遞迴,這樣可以將時間複雜度將為o n 在 演算法...

無序陣列中找第K個的數

題目分析 也就是從小往大排,第k小那個數。方法1 排序 nlogn 方法2 利用堆 nlogk 首先將前k個元素構建最大堆,堆頂是前k個元素中第k小的元素。這步複雜度klogk 遍歷剩餘元素 這步複雜度 n k logk 如果新元素 堆頂 堆頂不可能是第k大元素 移除堆頂 將新元素插入堆 否則 新元...