堆排序\链表实现局部排序
生活随笔
收集整理的這篇文章主要介紹了
堆排序\链表实现局部排序
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
以前面試時被問一個問題:有10萬個亂序的數,要前5個最大(或最小)的數?
作為一個沒好好學算法的人,還沒有算法時間、空間復雜度的概念,只提出了冒泡、快速排序等,然后取前5。這顯然不是合理的做法。
讀了幾本書,有一點點心得,下面介紹兩個做法:
假設:輸入為[31,5,12,24,41,63,7,61,42,21,9,123,24...] ,總數為N=100000,要求前M=5個最大的數
對10萬個建立二叉堆,然后應用堆排序5次,即取出前5個最大(或最小)的數。
只是一個可行的方法,在此不敖述,具體可參見《數據結構與算法分析:C語言描述》、《數據結構(C語言版)》嚴蔚敏等書中的堆排序。
考慮:能否維護一個數據結構用來存儲排好序的5個數,要求如果輸入數大于5個中最小的數,就將其插入至正確位置,并刪除最小的數。這樣對輸入進行一次遍歷,即可找出最大的5個數。
此處想到的是用單鏈表,首先對輸入中前5個數字升序排序,插入空的鏈表中。
Position Tmp,TmpCell; for( ; i<N; i++){ //對其余輸入進行一次遍歷P = Header(L); //表頭do{Tmp = P;//暫存前驅元,保存位置P = P->Next;//第一個元素if( input[i] <= P->Value ){ //小于第一個元素或者后面的某一個元素if(P != L->Next){ //input[i]大小介于第一個元素與此位置的元素Insert(in[i],L1,Tmp); //插入TmpCell = L1->Next;L1->Next = TmpCell->Next;free( TmpCell ); //擠出第一個元素,也就是5+1=6個中最小的元素}break;}else if(input[i] > P->Value && IsLast( P, L )){ //如果大于最后一個(也就是最大的)元素Insert(in[i],L,P); //插入到最后TmpCell = L->Next; L->Next = TmpCell->Next; free(TmpCell); //刪除第一個元素(6個中最小的)break;}} while( !IsLast(P, L) ); }
插入可能是這樣的:
刪除首元可能是這樣的:
小結:當輸入大數據量,而只需前m個最大(最小)值時,應用鏈表不失為一個好辦法,它只對輸入進行一次遍歷,時間復雜度O(N),空間也只不過額外是一個含6個元素的鏈表大小而已。
歡迎指教。
總結
以上是生活随笔為你收集整理的堆排序\链表实现局部排序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android入门(十二)SQLite事
- 下一篇: 构建之法第四章读后感