堆
邏輯結構:
1
/ \
1 3
/ \ / \
4 5 6 null
物理結構;
1.首先堆是一個完全二叉查找書(Complete Binary Search Tree)樹,觀察一下堆的邏輯結構和物理結構,邏輯結構是一顆完全二叉查找樹,物理結構是一個數組.
性質:堆的實現是通過構造二叉堆,這種數據結構具有一下幾個性質:
1.任意節點小於它的所有后裔,最小元素在堆的根上(堆序性)。
2.堆總是一顆完全樹。(Complete Tree)
3.將根節點的最大堆叫做Max Heap,最小堆叫做Min Heap。
4.左子節點=index of parent *2+1;
5.右子節點=index of parent*2+2;
支持的基本操作:
1.insert:向堆中插入一個新元素:Time Complete:O(log(n));
2.update:將新元素更新使其符合堆的性質:Time Complete:O(log(n));
3.get/top:獲取當前堆頂元素的值:Time Complete:O(1);
4.pop:刪除堆頂元素的值:Time Complete:O(log(n));
5.heapify:使得一個Unsorted array的元素變成一個堆:時間復雜度是O(c*n);
經典的算法題;
1.從沒有排序的n個元素中發現最小的K個元素。
重點:面試問到這個問題,首先需要向面試官問清楚具體情況,k和n的大小關系。
Solution1:
使用快排排序這個元素,然后返回前K個元素。
Solution2:
Step1:首先建立一個最小堆 O(n);
Step2:彈出前K個最小的元素 O(klogn);
依據上面堆的基本操作得出:Total Time Complete:O(n+klog(n));
Solution3:
Step1:建立一個包含K個元素的最大堆。
Step2:循環迭代從第k+1個元素到第n個元素,然后對於當前的X;
case1:
if X<max-heap.top(),max-heap.pop(),and max-heap.insert(X); --->log(k)
Case2:
else, do nothing;
依據上面的堆的基本操作得出: Total Time Complete:= O(K)+O((n-k)logk);
Case1: k <<< a e.g. k=20 n=1 billion
O(c * n) O(n*(logk))
依賴於具體的情況。
Case2: k~n e.g. k~0.5 billion n=1 billion
O(nlogn) O(nlogn)
結論:解法2和解法3,我們很難去說哪一個更好(因為它依賴於具體的k和n的大小).
Sulution4:
quick sort partition.(分區快排,直接干掉一半不需要的)
smaller larger
xxxxxxxxxxxxxxxxxxx P1 xxxxxxxxxxxxxxxxxxxx n = 10000, k=300;
pviot
smaller larger
xxxxx P2 xxxxx n = 5000,k = 300;
pivot
smaller larger
xx p3 xxx n=2500 ,k=300
pivot
smaller larger n = 2499 ,k = 299
x p4 xxxxx
Quick partiotion:
worst case:O(n*2)
Average case:O(n) n+n/2+n/4+n/8;