日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

堆排序\链表实现局部排序

發布時間:2025/5/22 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 堆排序\链表实现局部排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

以前面試時被問一個問題:有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個數字升序排序,插入空的鏈表中。

  • //簡單冒泡排序,輸入少,對整體性能影響可忽略不計 for(int j=1; j<M; j++){for(int k=0; k<M-j; k++){if(input[k]>input[k+1]){tmp = input[k];input[k] = input[k+1];input[k+1]=tmp;}} } for(int i=0; i<M; i++){Insert(input[i],L,P);//依次插入鏈表P = P->Next; }

    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個元素的鏈表大小而已。
    歡迎指教。

    總結

    以上是生活随笔為你收集整理的堆排序\链表实现局部排序的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。