對於有限的數集,可以通過把所有觀察值高低排序後找出正中間的乙個作為中位數。如果觀察值有偶數個,則中位數不唯一,通常取最中間的兩個數值的平均數作為中位數。
一般尋找中位數可以先將陣列排序,按照次序將中間的資料作為中位數即可,其時間複雜度主要取決於排序演算法的時間複雜度,利用快速排序可以將其控制為線性對數量級。
但是能否打破線性對數的限制呢?其中最關鍵的問題是,尋找中位數並不需要整個陣列完全有序,如果把多餘的元素排序省略掉,那麼就可以超越線性對數的限制實現最快的演算法。
啟發**於快速排序演算法中的切分法,比如我們需要找到陣列中第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 它的左右子樹也分別為二叉搜尋樹 除此之外,還有一點值得在意 二叉搜尋樹的最左節點是...