Python 言語----データ構造バイナリ ツリー 4 トラバーサル アルゴリズムの設計実験計画

1. 実験タスク

バイナリ リンク リストを記憶構造として使用し、プレオーダー、インオーダー、ポストオーダー、および階層順でバイナリ ツリーを走査するアルゴリズムを作成します。

2. 実験的な質問

バイナリ ツリーがバイナリ チェーンとして格納され、各ノード値が 1 つの文字であり、すべてのノード値が異なると仮定します。バイナリ ツリーのインオーダー シーケンスとポストオーダー シーケンスからバイナリ チェーンを構築し、検索、高さ、プレオーダー トラバーサル、インオーダー トラバーサル、ポストオーダー トラバーサル、およびレベル トラバーサル アルゴリズムを実装する実験プログラムを作成します。を作成し、関連データを使用してテストします。

3. 実験プロセス:

コレクションのインポート両端キューから必要なデータをインポートします。二分木における標準的な格納方法のノード構造は(data, lchild, rchild)であり、通常この方法はバイナリチェーンと呼ばれます。

from collections import deque
class BTNode:                                #二叉链中结点类
    def __init__(self,d=None):                        #构造方法
      self.data=d                               #结点值
      self.lchild=None                        #左孩子指针
      self.rchild=None  

次に二分木の基本演算アルゴリズムの実装と二分木のクラスの設計です。ここでは、ルート ノード b をバイナリ ツリーの一意の識別子として設計し、文字列を表すバイナリ チェーンのかっこを定義し、値 x (再帰アルゴリズムを使用) と高さ (Height) を検索しました。

class BTree:                                        #二叉树类
    def __init__(self,d=None):                        #构造方法
        self.b=None                                 #根结点指针

    def DispBTree(self):                       #返回二叉链的括号表示串
        return self._DispBTree1(self.b)

    def _DispBTree1(self,t):                      #被DispBTree方法调用
        if t==None:                                 #空树返回空串
            return ""
        else:
            bstr=t.data                          #输出根结点值
            if t.lchild!=None or t.rchild!=None:
                bstr+="("                    #有孩子结点时输出"("
                bstr+=self._DispBTree1(t.lchild)   #递归输出左子树
                if t.rchild!=None:
                    bstr+=","                 #有右孩子结点时输出","
                bstr+=self._DispBTree1(t.rchild)   #递归输出右子树
                bstr+=")"                    #输出")"
            return bstr

    def FindNode(self,x):                          #查找值为x的结点算法
        return self._FindNode1(self.b,x)

    def _FindNode1(self,t,x):                       #被FindNode方法调用
        if t==None: 
            return None                         #t为空时返回null
        elif t.data==x: 
            return t                        #t所指结点值为x时返回t
        else:
            p=self._FindNode1(t.lchild,x)        #在左子树中查找
            if p!=None: 
                return p                     #在左子树中找到p结点,返回p
            else:
                return self._FindNode1(t.rchild,x) #返回在右子树中查找结果

    def Height(self):                       #求二叉树高度的算法
        return self._Height1(self.b)

    def _Height1(self,t):                            #被Height方法调用
        if t==None:
            return 0                        #空树的高度为0
        else:
            lh=self._Height1(t.lchild)          #求左子树高度lchildh
            rh=self._Height1(t.rchild)          #求右子树高度rchildh
            return max(lh,rh)+1

次に、プレオーダー、ミッドオーダー、ポストオーダーでのバイナリ ツリーの走査を設計します。バイナリ ツリー トラバーサルは、バイナリ ツリー内のすべてのノードを特定の順序で訪問することであり、各ノードは 1 回だけ訪問されます。トラバース順序は、
最初の順序、中間の順序、および最後の順序です。

def PreOrder(bt):                               #先序遍历的递归算法
    _PreOrder(bt.b)
def _PreOrder(t):                                   #被PreOrder方法调用
    if t!=None:
        print(t.data,end=' ')                  #访问根结点
        _PreOrder(t.lchild)                       #先序遍历左子树
        _PreOrder(t.rchild)                       #先序遍历右子树
def InOrder(bt):                                    #中序遍历的递归算法
    _InOrder(bt.b)
def _InOrder(t):                                   #被InOrder方法调用
    if t!=None:
        _InOrder(t.lchild)                     #中序遍历左子树
        print(t.data,end=' ')                  #访问根结点
        _InOrder(t.rchild)                    #中序遍历右子树
def PostOrder(bt):                                #后序遍历的递归算法
    _PostOrder(bt.b)
def _PostOrder(t):                                  #被PostOrder方法调用
    if t!=None:
        _PostOrder(t.lchild)                   #后序遍历左子树
        _PostOrder(t.rchild)                   #后序遍历右子树
        print(t.data,end=' ')

バイナリ ツリーの構築: バイナリ チェーンは、後続シーケンスの post と中間シーケンス ins から構築されます。

def LevelOrder(bt):                              #层次遍历的算法
    qu=deque()                                      #将双端队列作为普通队列qu
    qu.append(bt.b)                               #根结点进队
    while len(qu)>0:                                #队不空循环
        p=qu.popleft()                         #出队一个结点
        print(p.data,end=' ')                    #访问p结点
        if p.lchild!=None:                      #有左孩子时将其进队
            qu.append(p.lchild)
        if p.rchild!=None:                      #有右孩子时将其进队
            qu.append(p.rchild)

def CreateBTree2(posts,ins):                        #由后序序列posts和中序序列ins构造二叉链
    bt=BTree()
    bt.b=_CreateBTree2(posts,0,ins,0,len(posts))
    return bt

def _CreateBTree2(posts,i,ins,j,n):
    if n<=0: return None
    d=posts[i+n-1]                           #取后序序列尾元素d
    t=BTNode(d)                               #创建根结点(结点值为d)
    p=ins.index(d)                                  #在ins中找到根结点的索引
    k=p-j                                #确定左子树中结点个数k
    t.lchild=_CreateBTree2(posts,i,ins,j,k)          #递归构造左子树
    t.rchild=_CreateBTree2(posts,i+k,ins,p+1,n-k-1)    #递归构造右子树
    return t

メインプログラムの設計

#主程序
ins=['D','G','B','A','E','C','F']
posts=['G','D','B','E','F','C','A']
print()
print("  中序:",end=' '); print(ins)
print("  后序:",end=' '); print(posts)
print("  构造二叉树bt")
bt=BTree()
bt=CreateBTree2(posts,ins)
print("  bt:",end=' '); print(bt.DispBTree())
x='X'
p=bt.FindNode(x)
if p!=None: print("  bt中存在"+x)
else: print("  bt中不存在"+x)
print("  bt的高度=%d" %(bt.Height()))
print("  先序序列:",end=' ');PreOrder(bt);print()
print("  中序序列:",end=' ');InOrder(bt);print()
print("  后序序列:",end=' ');PostOrder(bt);print()
print("  层次序列:",end=' ');LevelOrder(bt);print()

出力結果:

ここに画像の説明を挿入します

コード全体:

from collections import deque
class BTNode:                                #二叉链中结点类
   def __init__(self,d=None):                        #构造方法
      self.data=d                               #结点值
      self.lchild=None                        #左孩子指针
      self.rchild=None                        #右孩子指针
    
class BTree:                                        #二叉树类
    def __init__(self,d=None):                        #构造方法
        self.b=None                                 #根结点指针

    def DispBTree(self):                       #返回二叉链的括号表示串
        return self._DispBTree1(self.b)

    def _DispBTree1(self,t):                      #被DispBTree方法调用
        if t==None:                                 #空树返回空串
            return ""
        else:
            bstr=t.data                          #输出根结点值
            if t.lchild!=None or t.rchild!=None:
                bstr+="("                    #有孩子结点时输出"("
                bstr+=self._DispBTree1(t.lchild)   #递归输出左子树
                if t.rchild!=None:
                    bstr+=","                 #有右孩子结点时输出","
                bstr+=self._DispBTree1(t.rchild)   #递归输出右子树
                bstr+=")"                    #输出")"
            return bstr

    def FindNode(self,x):                          #查找值为x的结点算法
        return self._FindNode1(self.b,x)

    def _FindNode1(self,t,x):                       #被FindNode方法调用
        if t==None: 
            return None                         #t为空时返回null
        elif t.data==x: 
            return t                        #t所指结点值为x时返回t
        else:
            p=self._FindNode1(t.lchild,x)        #在左子树中查找
            if p!=None: 
                return p                     #在左子树中找到p结点,返回p
            else:
                return self._FindNode1(t.rchild,x) #返回在右子树中查找结果

    def Height(self):                       #求二叉树高度的算法
        return self._Height1(self.b)

    def _Height1(self,t):                            #被Height方法调用
        if t==None:
            return 0                        #空树的高度为0
        else:
            lh=self._Height1(t.lchild)          #求左子树高度lchildh
            rh=self._Height1(t.rchild)          #求右子树高度rchildh
            return max(lh,rh)+1

def PreOrder(bt):                               #先序遍历的递归算法
    _PreOrder(bt.b)
def _PreOrder(t):                                   #被PreOrder方法调用
    if t!=None:
        print(t.data,end=' ')                  #访问根结点
        _PreOrder(t.lchild)                       #先序遍历左子树
        _PreOrder(t.rchild)                       #先序遍历右子树
def InOrder(bt):                                    #中序遍历的递归算法
    _InOrder(bt.b)
def _InOrder(t):                                   #被InOrder方法调用
    if t!=None:
        _InOrder(t.lchild)                     #中序遍历左子树
        print(t.data,end=' ')                  #访问根结点
        _InOrder(t.rchild)                    #中序遍历右子树
def PostOrder(bt):                                #后序遍历的递归算法
    _PostOrder(bt.b)
def _PostOrder(t):                                  #被PostOrder方法调用
    if t!=None:
        _PostOrder(t.lchild)                   #后序遍历左子树
        _PostOrder(t.rchild)                   #后序遍历右子树
        print(t.data,end=' ')                  #访问根结点
   
def LevelOrder(bt):                              #层次遍历的算法
    qu=deque()                                      #将双端队列作为普通队列qu
    qu.append(bt.b)                               #根结点进队
    while len(qu)>0:                                #队不空循环
        p=qu.popleft()                         #出队一个结点
        print(p.data,end=' ')                    #访问p结点
        if p.lchild!=None:                      #有左孩子时将其进队
            qu.append(p.lchild)
        if p.rchild!=None:                      #有右孩子时将其进队
            qu.append(p.rchild)

def CreateBTree2(posts,ins):                        #由后序序列posts和中序序列ins构造二叉链
    bt=BTree()
    bt.b=_CreateBTree2(posts,0,ins,0,len(posts))
    return bt

def _CreateBTree2(posts,i,ins,j,n):
    if n<=0: return None
    d=posts[i+n-1]                           #取后序序列尾元素d
    t=BTNode(d)                               #创建根结点(结点值为d)
    p=ins.index(d)                                  #在ins中找到根结点的索引
    k=p-j                                #确定左子树中结点个数k
    t.lchild=_CreateBTree2(posts,i,ins,j,k)          #递归构造左子树
    t.rchild=_CreateBTree2(posts,i+k,ins,p+1,n-k-1)    #递归构造右子树
    return t

#主程序
ins=['D','G','B','A','E','C','F']
posts=['G','D','B','E','F','C','A']
print()
print("  中序:",end=' '); print(ins)
print("  后序:",end=' '); print(posts)
print("  构造二叉树bt")
bt=BTree()
bt=CreateBTree2(posts,ins)
print("  bt:",end=' '); print(bt.DispBTree())
x='X'
p=bt.FindNode(x)
if p!=None: print("  bt中存在"+x)
else: print("  bt中不存在"+x)
print("  bt的高度=%d" %(bt.Height()))
print("  先序序列:",end=' ');PreOrder(bt);print()
print("  中序序列:",end=' ');InOrder(bt);print()
print("  后序序列:",end=' ');PostOrder(bt);print()
print("  层次序列:",end=' ');LevelOrder(bt);print()

おすすめ

転載: blog.csdn.net/qq_62127918/article/details/130711986