0

組み込みのヒープ関数を使用せずに、Python で完全な MIN-HEAP 実装を構築する必要があります。

したがって、0 からの python 番号リスト要素を考慮した、親、左の子、および右の子の定義があります。

from random import randint
import math 

def parent(i):
    x = int(l.index(l[i])) #########3
    y = int(math.floor(x/2))
    return y-1  

def lchild(i):
    x = int(l.index(l[i]))
    y = int(math.floor(x*2))
    return y-1

def rchild(i):
    x = int(l.index(l[i]))
    y = int(math.floor(x*2 + 1))
    return y-1

次に、(疑似)ランダムリストをリストlに生成するコードの一部があります。

l = []
dl = int(input)

for i in range (0, dl):
    x = int(randint(1,100)) 
    l.append(x)             

そして、この時点まではすべてうまくいきます。次に、テーブルlを最小ヒープにする関数 bkop があります。

def bkop(l):
        j = 0
        for i in range(0, len(l)):
                if int(l[i]) < int(parent(l[i])): #########2
                        l[i], l[parent(i)] = l[parent(i)], l[i]
                        j = j+1
                if j != 0:
                        bkop(l)

次に、プログラムを実行して結果を確認します。

bkop(l) #########1
print l

######### でマークした 3 行を指す範囲外のエラー リスト インデックスでプログラムがクラッシュします。私は約 1 か月前にこれを書き始めましたが、確かにその親、lchild、rchild は当時働いていました。何が悪いのかわかりますか?

EDIT1: 親/子/子の定義を修正しました。確認しましたが、正しい値が返されます。コードは次のとおりです。

def parent(i):
    x = i + 1
    y = x//2
    return y-1

def lchild(i):
    x = i + 1
    y = x*2
    return y-1

def rchild(i):
    x = i + 1
    y = x*2 + 1
    return y-1

ランダム リストを生成する関数はほとんどそのままです。次に、この bkop 関数があります ( lリストから最小ヒープを作成します)。意図的に前後に print を使用して、機能するかどうかを確認します...そして機能しません。どちらも同じリストを返し、コンパイルエラーなどはありません。それを修正する方法はありますか?

print(l)
def bkop(l): 
        j = 0
        for i in range(0, len(l)):
                if l[i] < parent(i):
                        l[i], l[parent(i)] = l[parent(i)], l[i]
                        j = j+1
                if j != 0:
                        bkop(l)
bkop(l)
print l

EDIT2:わかりましたので、あなたが提案したようにbkopを修正しました:

print bkop(l)
def bkop(l):
        j = 0
        for i in range(1, len(l)):
                if l[i] < l[parent(i)]:
                        l[i], l[parent(i)] = l[parent(i)], l[i]
                        j = j+1
                if j != 0:
                        bkop(l)
bkop(l)
print bkop(l)

しかし、それを実行すると、最初にランダムに生成されたテーブルが取得され (当然のことですが)、最小ヒープ テーブルの代わりに、以下のようにNone値が取得されます。

[34, 9, 94, 69, 77, 33, 56]
None

何か案は?l[i] を親と比較するのではなく、l[i] を左右の子と比較するのではなく、別の方法で行う必要がありますか?

4

2 に答える 2

2

最初に:と関数parentに問題があります:lchildrchild

  • l[index]指定されたインデックスの値を取得します。

  • l.index(...)指定された値のインデックスを取得します。

特定のインデックスで値のインデックスを取得しようとしています。みたいなx + 1 - 1。項目が一意である場合、その計算されたインデックスは常に開始時のインデックスと同じになります。重複がある場合、関数はそのインデックスで最初に出現する値の親、左および右の子を計算します。それはおそらくあなたが望むものではありません。に設定xするiか、完全に削除xします。

実際の問題は次のとおりです。

parentlchildおよび関数rchildは で動作するように設計されていますが、 at indexindexの値を関数に渡しています。liparent(l[i])

リスト内の値が可能なインデックス範囲よりもはるかに大きい可能性があるため、リスト インデックスが範囲外になっています。おそらく、インデックスを直接渡したいでしょう。

さらに:

parent、正しくない値lchildを返します。rchild他のすべてのものなしでこれらの機能をテストしてください!

結果は次のようになるはずです。

  • parent(1) == parent(2) == 0
  • lchild(0) == 1
  • rchild(0) == 2

あなたの定義は異なる値を返します。

いくつかのマイナーなこと:

  • これらのランダムなintキャストはすべて役に立ちません。intto をキャストしても何も起こりintません。本当にキャストが必要な唯一の行は: ``dl = int(input)`
  • int(math.floor(x/2)). x // 2代わりに整数除算を使用してください
  • int(math.floor(x*2)). 2 の整数倍は整数です。その必要はありませんfloor

編集関数 には2つの問題がありますbkop

  • l[i] < parent(i)値をインデックスと比較します。i親インデックスではなく、その親値に値を適用したいと思います。
  • index の値i == 0を の値と比較します。これはリストをラップアラウンドし、おそらくあなたが望むものではありません. インデックスには親がないため、それを親と比較しようとしないでください。0parent(0) == -10

編集2

bkopリストを返しませんが、インプレースで変更します。ちょうどprint(l)最後に。元のリストが変更されていることがわかります。

于 2016-01-23T15:02:59.887 に答える