快速切分法尋找中位數的遞迴與非遞迴實現

2021-07-06 08:21:57 字數 1420 閱讀 2434

對於有限的數集,可以通過把所有觀察值高低排序後找出正中間的乙個作為中位數。如果觀察值有偶數個,則中位數不唯一,通常取最中間的兩個數值的平均數作為中位數。

一般尋找中位數可以先將陣列排序,按照次序將中間的資料作為中位數即可,其時間複雜度主要取決於排序演算法的時間複雜度,利用快速排序可以將其控制為線性對數量級。

但是能否打破線性對數的限制呢?其中最關鍵的問題是,尋找中位數並不需要整個陣列完全有序,如果把多餘的元素排序省略掉,那麼就可以超越線性對數的限制實現最快的演算法。

啟發**於快速排序演算法中的切分法,比如我們需要找到陣列中第k小的元素,首先將陣列a[lo,hi]切分返回整數j,使得a[lo,j-1]都小於等於a[j],而a[j+1,hi]都大於等於a[j],如果j==k,那麼j位置的元素就是我們要找的第k小的元素,而如果j>k,就要切分左子陣列,如果jpublic

class

select

// 找出陣列中第k小的元素,非遞迴實現

public

static

comparableselect1(comparable a, int k) else

if (j > k) else

if (j < k)

}return a[k];

}// 找出陣列中第k小的元素,遞迴實現

public

static

comparableselect2(comparable a, int k, int lo, int hi) else

if (j > k) else

}public

static

intpartition(comparable a, int lo, int hi)

}while (less(v, a[--j]))

}if (i >= j)

exch(a, i, j);// 交換左右逆序元素

}exch(a, lo, j);// 將切分元素放在切分位置

return j;

}@suppresswarnings("unchecked")

public

static

boolean

less(comparablev, comparablew)

private

static

void

exch(comparable a, int i, int j)

public

static

void

main(string args)

}

尋找兩個正序陣列的中位數 二分法學習

給定兩個大小為 m 和 n 的正序 從小到大 陣列 nums1 和 nums2。請你找出這兩個正序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設 nums1 和 nums2 不會同時為空。示例 1 nums1 1,3 nums2 2 則中位數是 2.0 示例 2 nums...

快速排序的遞迴形式與非遞迴形式 C 版

快排的理解 設要排序的陣列是 a 0 a n 1 首先任意選取乙個資料 通常選用陣列的第乙個數 作為關鍵資料,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排序。值得注意的是,快速排序不是一種穩定的排序演算法,也就是說,多個相同的值的相對位置也許會在演算法結束時產...

二叉搜尋樹的實現(查詢,插入,刪除的遞迴與非遞迴)

bst定義 二叉搜尋樹 又稱二叉排序樹,它或者是一棵空樹,或者是具有以下性質的二叉樹 1 若它的左子樹不為空,則左子樹上所有節點的值都小於根節點的值 2 若它的右子樹不為空,則右子樹上所有節點的值都大於根節點的值 3 它的左右子樹也分別為二叉搜尋樹 除此之外,還有一點值得在意 二叉搜尋樹的最左節點是...