[python] n個(gè)數(shù)中K個(gè)最小值

code:

# 類似于快排的思想跨释,不同的地方在于每趟只需要往一個(gè)方向走
# 按照從小到大的順序胸私,尋找前K個(gè)最小值
def qselect(ary_list, k):
    if len(ary_list) < k:
        return ary_list

    tmp = ary_list[0]
    left = [x for x in ary_list[1:] if x <= tmp] + [tmp]
    llen = len(left)
    if llen == k:
        return left
    if llen > k:
        return qselect(left, k)
    else:
        right = [x for x in ary_list[1:] if x > tmp]
        return left + qselect(right, k-llen)
    pass

最大堆
假設(shè)數(shù)組長度為N,首先取前K個(gè)數(shù)鳖谈,構(gòu)建二叉堆(大頂堆)岁疼,然后將剩余N-K個(gè)元素,依次與堆頂元素進(jìn)行比較缆娃,若小于堆頂元素捷绒,則替換, 并重新為大頂堆贯要。

# 最大堆下沉調(diào)整暖侨,始終保持最大堆
def downAdjust(ary_list, parent_index, length):
    tmp = ary_list[parent_index]
    child_index = 2 * parent_index + 1

    while child_index < length:
        if child_index + 1 < length and ary_list[child_index + 1] > ary_list[child_index]:
            child_index += 1

        if tmp >= ary_list[child_index]:
            break

        ary_list[parent_index] = ary_list[child_index]
        parent_index = child_index
        child_index = 2 * parent_index + 1

    ary_list[parent_index] = tmp
    pass

# 構(gòu)建堆
def build_heap(ary_list, k):
    index = k // 2 - 1  # 最后一個(gè)非葉子結(jié)點(diǎn)
    while index >= 0:
        downAdjust(ary_list, index, k)
        index -= 1
    pass


# 利用最大堆找出前K個(gè)最小值
# 每次從原數(shù)組中拿出一個(gè)元素和當(dāng)前堆頂值比較,
# 然后判斷是否可以放入崇渗,放入后繼續(xù)調(diào)整堆結(jié)構(gòu)
def heapK(ary, nums, k):
    if nums <= k:
        return nums
        
    ks = ary[:k]
    build_heap(ks, k)           # 構(gòu)建大頂堆(先不排序)
    # print('build heap:', ks)
    
    for index in range(k, nums):
        ele = ary[index]
        if ks[0] > ele:
            ks[0] = ele
            downAdjust(ks, 0, k)
            # print('heap adjust:', ks)

    # 如果需要?jiǎng)t輸出排序結(jié)果
    # heap_sort(ks)
    return ks
    pass


if __name__ == '__main__':

    # *** 測試方法1
    ary_list = [10, 2, 38, 9, 22, 53, 47, 7, 3, 97]
    nums = len(ary_list)
    print('{} original data:'.format(nums), ary_list)

    # # 原始數(shù)組的排列順序(作為ks的對(duì)比)
    # build_heap(ary_list, nums)
    # heap_sort(ary_list)
    # print('{} original sorted data:'.format(nums), ary_list)

    for k in range(6, nums + 1):
        ks = heapK(ary_list, nums, k)
        print('{}th data:'.format(k), ks)
        break
    pass

順序

# 堆排序(最大堆)
def heap_sort(ary):
    length = len(ary)

    index = length - 1
    # 依次移除堆頂元素(放入末尾)字逗,并將末尾元素放在堆頂,進(jìn)行下沉調(diào)整宅广,
    # 使得每次都會(huì)有非最大值上浮到堆頂葫掉,并重新調(diào)整為大頂堆;
    # 然后再重復(fù)上述操作跟狱。
    while index >= 0:
        tmp = ary[0]
        ary[0] = ary[index]
        ary[index] = tmp
        downAdjust(ary, 0, index)
        index -= 1

    pass
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末俭厚,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子驶臊,更是在濱河造成了極大的恐慌挪挤,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件关翎,死亡現(xiàn)場離奇詭異扛门,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)笤休,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來症副,“玉大人店雅,你說我怎么就攤上這事政基。” “怎么了闹啦?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵沮明,是天一觀的道長。 經(jīng)常有香客問我窍奋,道長荐健,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任琳袄,我火速辦了婚禮江场,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘窖逗。我一直安慰自己址否,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布碎紊。 她就那樣靜靜地躺著佑附,像睡著了一般。 火紅的嫁衣襯著肌膚如雪仗考。 梳的紋絲不亂的頭發(fā)上音同,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音秃嗜,去河邊找鬼权均。 笑死,一個(gè)胖子當(dāng)著我的面吹牛痪寻,可吹牛的內(nèi)容都是我干的螺句。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼橡类,長吁一口氣:“原來是場噩夢啊……” “哼蛇尚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起顾画,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤取劫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后研侣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谱邪,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年庶诡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惦银。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖扯俱,靈堂內(nèi)的尸體忽然破棺而出书蚪,到底是詐尸還是另有隱情,我是刑警寧澤迅栅,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布殊校,位于F島的核電站,受9級(jí)特大地震影響读存,放射性物質(zhì)發(fā)生泄漏为流。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一让簿、第九天 我趴在偏房一處隱蔽的房頂上張望敬察。 院中可真熱鬧,春花似錦拜英、人聲如沸静汤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虫给。三九已至,卻和暖如春侠碧,著一層夾襖步出監(jiān)牢的瞬間抹估,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工弄兜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留药蜻,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓替饿,卻偏偏與公主長得像语泽,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子视卢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容