データ構造:二分探索木の実装

二叉查找树

バイナリ ツリーは、最大 2 つのサブツリーをノードとして持つツリー状の構造であり、左サブツリーおよび右サブツリーと呼ぶことができます。しかし、通常の二分木の場合、左側の部分木と右側の部分木に何が格納されているかを示すのに十分な情報がなく、効率的な情報検索を実行する方法がありません。検索効率を向上させるために、二分木を二分探索木(Binary Search Tree)にアップグレードします。

二分探索木は、次の定義に準拠する二分木です。

1. ノードの左側のサブツリー内のすべてのノード キー値がノードより小さい。

2. ノードの右サブツリー内のすべてのノード キー値がノードより大きい。

3. 重複したキー値がないこと

このように、キーの値に基づいてノードを検索する場合、方向を指定して検索することはできるでしょうか? ルート ノードから開始して、キー値がターゲット キー値と等しくなく、ターゲット キー値が現在のノードより小さい場合は、左側のサブツリーに移動して検索を続行します。そうでない場合は、右側のサブツリーに移動します。こうすることで、毎回確実にレベルを 1 つ進めることができます。このようにして、クエリ効率が大幅に向上します。

节点结构定义
class BSTNode{
public:
    BSTNode(int d=0,BSTNode* l=0,BSTNode* r=0):data(d),left(l),right(r){};
    int data;
    BSTNode* left;
    BSTNode* right;
 
};

この記事のコード実装は、関連するアルゴリズムを説明することのみを目的としており、工業デザインに直接適用することはできないため、ここではテンプレートを使用しません。ノードデータは全て整数データである。

データ ノードが必要です。左サブツリー ポインタは左、右サブツリー ポインタは右です。

二叉查找树结构定义
class BST{
public:
    BST(BSTNode* r=0):root(r){
        size = 0;
    }
    ~BST();
    enum dfstype{PRE=0,IN=1,POST=2};
    enum deletetype{MERGE=0,COPY=1};
    //插入
    void insert(int data);
    //查找
    bool find(int data) const;
    //层次遍历
    void bfs() const;
    //深搜遍历
    void dfs(BST::dfstype) const;
    //递归写法
    void predfs(BSTNode*) const;
    void indfs(BSTNode*) const;
    void postdfs(BSTNode*) const;
    //回溯写法
    void predfsNormal() const;
    void indfsNormal() const;
    void postdfsNormal() const;
    //计数写法
    void predfsCount() const;
    void indfsCount() const;
    void postdfsCount() const;
    void clearTime();
    //删除相关
    void deleteELement(int data,enum deletetype type);
    void mergeDelete(BSTNode*&);
    void copyDelete(BSTNode*&);
    //平衡树
    /*
    *中序遍历得到有序数组,然后根据数组重新构建树,效率较低
    */
    void balance();
    void balance(int data[],int first,int last);
    //DSW旋转算法
    void rightRotate(BSTNode* z,BSTNode* f,BSTNode* n);
    void leftRotate(BSTNode* z,BSTNode* f,BSTNode* n);
    void createList();
    void createPerfectTree();
    //AVL树
 
    //其它
    int getSize() const;
    void clear();//清空节点
     
private:
    BSTNode* root;
    int size;
};
插入算法
void BST::insert(int data){
    BSTNode* newnode = new BSTNode(data);
    BSTNode* temp = root;
    BSTNode* pre = 0;
    while(temp!=0){
        pre = temp;
        if(temp->data>data){
            temp = temp->left;
        }else if(temp->data<data){
            temp = temp->right;
        }else{
            return;
        }
    }
    if(pre==0)
        root = newnode;
    else{
        if(pre->data>data){
            pre->left = newnode; 
        }else{
            pre->right = newnode;
        }
    }
    size++;
}
查找元素算法
bool BST::find(int data) const{
    BSTNode* temp = root;
    while(temp!=0)
    {
        if(temp->data==data)
            return true;
        else if(temp->data>data)
            temp = temp->left;
        else
            temp = temp->right;
    }
    return false;
}
树的遍历
树的遍历
方法有两种:深度优先遍历(Depth First Search,DFS),广度优先遍历(Breadth First Search,BFS)
广度优先遍历利用队列一层一层访问即可。
深度优先遍历分未3种:先序、中序、后序遍历。
值得一提的是,对于符合定义的二叉查找树来说,中序遍历的结果恰好是有序的(有趣不有趣?),所以中序遍历应用最为广泛的。

おすすめ

転載: blog.csdn.net/qq_32301683/article/details/101381758