1. 程式人生 > >數據結構開發(22):二叉樹的轉換、深層特性與存儲結構設計

數據結構開發(22):二叉樹的轉換、深層特性與存儲結構設計

his 9.png 二叉 klist efi remove ren binary 兩個

0.目錄

1.樹到二叉樹的轉換

2.二叉樹的深層特性

3.二叉樹的存儲結構設計

4.小結

1.樹到二叉樹的轉換

通用樹結構的回顧:

  • 雙親孩子表示法
    1. 每個結點都有一個指向其雙親的指針
    2. 每個結點都有若幹個指向其孩子的指針

技術分享圖片

另一種樹結構模型:

  • 孩子兄弟表示法
    1. 每個結點都有一個指向其第一個孩子的指針
    2. 每個結點都有一個指向其第一個右兄弟的指針

技術分享圖片

孩子兄弟表示法的特點:

  1. 能夠表示任意的樹形結構
  2. 每個結點包含一個數據成員和兩個指針成員
  3. 孩子結點指針和兄弟結點指針構成了“樹權”

二叉樹的定義:

  • 二叉樹是由 n ( n ≥ 0 ) 個結點組成的有限集合,該集合或者為空,或者是由一個根結點加上兩棵
    分別稱為左子樹右子樹的、互不相交的二叉樹組成。

二叉樹的5種形態:
技術分享圖片

特殊的二叉樹:

  • 滿二叉樹 (Full Binary Tree)
    1. 如果二叉樹中所有分支結點的度數都為 2,且葉子結點都在同一層次上,則稱這類二叉樹為滿叉樹。
  • 完全二叉樹 (Complete Binary Tree)
    1. 如果一棵具有 n 個結點的高度為 k 的二叉樹,它的每一個結點都與高度為 k 的滿二叉樹中編號為 1 — n 的結點一一對應,則稱這棵二叉樹為完全二叉樹。( 從上到下從左到右編號 )

完全二叉樹的特性:

  • 同樣結點數的二叉樹,完全二叉樹的高度最小
  • 完全二叉樹的葉結點僅出現在最下面兩層
    1. 最底層的葉結點一定出現在左邊
    2. 倒數第二層的葉結點一定出現在右邊
    3. 完全二叉樹中度為 1 的結點只有左孩子

技術分享圖片

2.二叉樹的深層特性

性質1:
技術分享圖片

性質2:
技術分享圖片

性質3:
技術分享圖片

性質4:
技術分享圖片

性質5(這一條性質為完全二叉樹所特有,普通二叉樹不具備。):
技術分享圖片

3.二叉樹的存儲結構設計

本節目標:

  • 完成二叉樹二叉樹結點的存儲結構設計

技術分享圖片

設計要點:

  • BTree 為二叉樹結構,每個結點最多只有兩個後繼結點
  • BTreeNode 只包含 4 個固定的公有成員 ( 哪4個? )
  • 實現樹結構的所有操作 ( 增,刪,查,等 )

BTreeNode 的設計與實現:
技術分享圖片

BTree 的設計與實現:
技術分享圖片

BTree ( 二叉樹結構 ) 的實現架構:
技術分享圖片

重構父類TreeNode類和Tree類:
TreeNode.h

#ifndef TREENODE_H
#define TREENODE_H

#include "Object.h"

namespace StLib
{

template <typename T>
class TreeNode : public Object
{
protected:
    bool m_flag;

    TreeNode(const TreeNode<T>&);
    TreeNode<T>& operator = (const TreeNode<T>&);

    void* operator new(size_t size) throw()
    {
        return Object::operator new(size);
    }
public:
    T value;
    TreeNode<T>* parent;

    TreeNode()
    {
        m_flag = false;
        parent = NULL;
    }

    bool flag()
    {
        return m_flag;
    }

    virtual ~TreeNode() = 0;
};

template <typename T>
TreeNode<T>::~TreeNode()
{

}

}

#endif // TREENODE_H

Tree.h

#ifndef TREE_H
#define TREE_H

#include "TreeNode.h"
#include "SharedPointer.h"

namespace StLib
{

template <typename T>
class Tree : public Object
{
protected:
    TreeNode<T>* m_root;

    Tree(const Tree<T>&);
    Tree<T>& operator = (const Tree<T>&);
public:
    Tree() { m_root = NULL; }
    virtual bool insert(TreeNode<T>* node) = 0;
    virtual bool insert(const T& value, TreeNode<T>* parent) = 0;
    virtual SharedPointer< Tree<T> > remove(const T& value) = 0;
    virtual SharedPointer< Tree<T> > remove(TreeNode<T>* node) = 0;
    virtual TreeNode<T>* find(const T& value) const = 0;
    virtual TreeNode<T>* find(TreeNode<T>* node) const = 0;
    virtual TreeNode<T>* root() const = 0;
    virtual int degree() const = 0;
    virtual int count() const = 0;
    virtual int height() const = 0;
    virtual void clear() = 0;
};

}

#endif // TREE_H

修改對應的GTreeNode類:
GTreeNode.h

#ifndef GTREENODE_H
#define GTREENODE_H

#include "TreeNode.h"
#include "LinkList.h"

namespace StLib
{

template <typename T>
class GTreeNode : public TreeNode<T>
{
public:
    LinkList<GTreeNode<T>*> child;

    static GTreeNode<T>* NewNode()
    {
        GTreeNode<T>* ret = new GTreeNode<T>();

        if( ret != NULL )
        {
            ret->m_flag = true;
        }

        return ret;
    }
};

}

#endif // GTREENODE_H

在StLib中定義BTreeNode類和BTree類:
BTreeNode.h

#ifndef BTREENODE_H
#define BTREENODE_H

#include "TreeNode.h"

namespace StLib
{

template <typename T>
class BTreeNode : public TreeNode<T>
{
public:
    BTreeNode<T>* left;
    BTreeNode<T>* right;

    BTreeNode()
    {
        left = NULL;
        right = NULL;
    }

    static BTreeNode<T>* NewNode()
    {
        BTreeNode<T>* ret = new BTreeNode<T>();

        if( ret != NULL )
        {
            ret->m_flag = true;
        }

        return ret;
    }
};

}

#endif // BTREENODE_H

BTree.h

#ifndef BTREE_H
#define BTREE_H

#include "Tree.h"
#include "BTreeNode.h"
#include "Exception.h"
#include "LinkQueue.h"

namespace StLib
{

template <typename T>
class BTree : public Tree<T>
{
public:
    bool insert(TreeNode<T>* node)
    {
        bool ret = true;

        return ret;
    }

    bool insert(const T& value, TreeNode<T>* parent)
    {
        bool ret = true;

        return ret;
    }

    SharedPointer< Tree<T> > remove(const T& value)
    {
        return NULL;
    }

    SharedPointer< Tree<T> > remove(TreeNode<T>* node)
    {
        return NULL;
    }

    BTreeNode<T>* find(const T& value) const
    {
        return NULL;
    }

    BTreeNode<T>* find(TreeNode<T>* node) const
    {
        return NULL;
    }

    BTreeNode<T>* root() const
    {
        return dynamic_cast<BTreeNode<T>*>(this->m_root);
    }

    int degree() const
    {
        return NULL;
    }

    int count() const
    {
        return NULL;
    }

    int height() const
    {
        return NULL;
    }

    void clear()
    {
        this->m_root = NULL;
    }

    ~BTree()
    {
        clear();
    }
};

}

#endif // BTREE_H

4.小結

  • 通用樹結構采用了雙親結點表示法進行描述
  • 孩子兄弟表示法有能力描述任意類型的樹結構
  • 孩子兄弟表示法能夠將通用樹轉化為二叉樹
  • 二叉樹是最多只有兩個孩子的樹

數據結構開發(22):二叉樹的轉換、深層特性與存儲結構設計