該題目的兩種實現方式,第一種是用堆排序(其中陣列用到了二叉樹的性質),第二種是利用快速排序來實現.
最大堆進行公升序排序,主要步驟是
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]重新調整為最大值。 依次類推,直到整個數列都是有序的。
1static
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)的期望時間複雜度。
1static
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大元素 移除堆頂 將新元素插入堆 否則 新元...