zoukankan      html  css  js  c++  java
  • 二叉树

    1. 定义和主要特性

    满二叉树:每一个节点或者分支节点,并恰好有两个非空节点,或者是叶节点

    完全二叉树:有严格的形状要求,从根节点起每一层从左到右填充,一棵高度为d的完全二叉树除了d-1层以外,每一层都是满的,底层叶节点集中在左边的若干位置上。

    2. 满二叉树定理:

    非空满二叉树的叶节点数等于分支节点数加1

    一棵非空二叉树空子树的数目等于节点数目加1

    3. 二叉树的抽象数据类型

    template <typename E> class BinNode {
    public:
        virtual ~BinNode() {}    // Base destructor
        
        // Return the node's value
        virtual E& element() = 0;
    
        // Set the node's value
        virtual void setElement(const E&) = 0;
    
        // Return the node's left child
        virtual BinNode* left() const = 0;
    
        // Set the node's left child
        virtual void setLeft(BinNode*) = 0;
    
        // Return the node's right child 
        virtual BinNode* right() const = 0;
    
        // Set the node's right child
        virtual void setRight(BinNode*) = 0;
    
        // Return true if the node is a leaf, false otherwise
        virtual bool isLeaf() = 0;
    };

    4. 遍历二叉树

    前序遍历要求先访问root,再访问它的子节点

    template <typename E>
    void preorder(BinNode<E> *root){
        if(root == NULL) return;
        visit(root);
        preorder(root->left());
        preorder(root->right());  
    }

    计算二叉树节点的数目

    template <typename E>
    int count(BinNode<E> *root){
        if(root == NULL) return 0;
        return 1 + count(root -> left()) + count(root -> right());     
    }

    给定一棵二叉树,判断下面的性质是否成立:

    对于任意一个节点A,左子树的所有节点值都小于A的节点值,其右子树的所有节点值都大于A的节点值

    template <typename Key, typename E>
    bool checkBST(BSTNode<Key, E> *root, Key low, Key high){
        if(root == NULL) return true;
        Key rootKey = root->key();
        if((rootKey < low) || (rootKey > high))    return false;
        if(!checkBST<Key, E>(root -> left(), low, rootKey))    return false;
        return checkBST<Key, E>(root -> right(), rootKey, high);
    }

    5. 使用指针实现二叉树

    BSTNode类包含一个E类型的数据成员,它是模板的第二个参数,为了实现二叉检索树,需要添加一个新的域和对应的访问方式,以存储关键码,其类型由模板的第一个参数Key决定,每一个BST都包含有两个指针,一个指向左子节点,一个指向右子节点。

    #include "BinNode.h"
    
    template <typename Key, typename E>
    class BSTNode : public BinNode<E> {
    private:
        Key k;
        E it;
        BSTNode *lc;
        BSTNode *rc;
    
    public:
        // two constructors -- with and without initial values
        BSTNode() {
            lc = rc = NULL;
        }
    
        BSTNode(Key k, E it, BSTNode *lc = NULL, BSTNode *rc = NULL) {
            this->k = k;
            this->it = it;
            this->lc = lc;
            this->rc = rc;
        }
    
        // destructors
        ~BSTNode() {}
    
        // Function to set and return the value and key
        E& element(){
            return it;
        }
    
        void setElement(const E& it){
            this->it = it;
        }
    
        Key& key(){
            return k;
        }
    
        void setKey(const Key& k){
            this->k = k;
        }
    
        // Functions to set and return the children
        inline BSTNode* left() const{
            return lc;
        }
    
        void setLeft(BinNode<E> *lc) {
            this->lc = (BSTNode *)lc;
        }
    
        inline BSTNode* right() const {
            return rc;
        }
    
        void setRight(BinNode<E> *rc) {
            this->rc = (BSTNode *)rc;
        }
    
        // return true if it is a leaf, flase otherwise
        bool isLeaf() {
            return (lc == NULL) && (rc == NULL);
        }
    };

    6. 使用数组实现完全二叉树

    完全二叉树最重要的用途在于实现堆结构,堆经常用来实现优先队列和外排序算法

    完全二叉树计算亲属节点下标的公式:

    Parent(r) = (r - 1) / 2

    Leftchild(r) = 2r + 1  当2r + 1 < n时

    Rightchild(r) = 2r + 2  当2r + 2 < n时

    Leftsibling(r) = r - 1  当r为偶数的时

    Rightsibling(r) = r + 1  当r为奇数时,当r + 1 < n时

    7. 二叉检索树:Binary Search Tree ,BST

    对于二叉检索树的任何一个结点,设其值为K,则节点左子树中的任意一个结点都小于K,该节点的右子树中任意一个结点的值都大于或者等于K

    如果按照中序遍历将各个节点打印出来,就会得到从小到大排列的节点

    #include "BSTNode.h"
    #include "Dictionary.h"
    template <typename Key, typename E>
    class BST : public Dictionary<Key, E> {
    private:
        BSTNode<Key, E>* root;    // root of the BST
        int nodeCount;    // number of nodes in the BST
    
        // Private "helper" functions
        void clearHelp(BSTNode<Key, E>*);
        BSTNode<Key, E>* insertHelp(BSTNode<Key, E>*, const Key&, const E&);
        BSTNode<Key, E>* deleteMin(BSTNode<Key, E>*);
        BSTNode<Key, E>* getMin(BSTNode<Key, E>*);
        BSTNode<Key, E>* removeHelp(BSTNode<Key, E>*, const Key&);
        E findHelp(BSTNode<Key, E>*, const Key&) const;
        void printHelp(BSTNode<Key, E>*, int) const;
    public:
        BST() {
            root = NULL;
            nodeCount = 0;
        }
    
        ~BST() {
            clearHelp(root);
        }
    
        void clear() {
            clearHelp(root);
            root = NULL;
            nodeCount = 0;
        }
    
        // Insert a record into the tree.
        // k Key value of the record.
        // e The record to insert
        void insert(const Key& k, const E& e) {
            root = insertHelp(root, k, e);
            nodeCount++;
        }
    
        // Remove a record from the tree.
        // k Key value of record to remove.
        // Retrun: The record removed, or NULL if there is none.
        E remove(const Key& k) {
            E temp = findHelp(root, k);
            if (temp != NULL) {
                root = removeHelp(root, k);
                nodeCount--;
            }
            return temp;
        }
    
        // Remove and return the root node form the dictionary
        // Return: The record removed, null if tree is empty.
        E removeAny() {
            if (root != NULL) {
                E temp = root->element();
                root = removeHelp(root, root->key());
                nodeCount--;
                return temp;
            }
            else return NULL;
        }
    
        // Return Record with key value k, NULL if none exist
        // k: The key value to find
        // Return some record matching "k"
        // Return true if such exists false otherwise. If
        // multiple records match "k", return an arbitrary one.
        E find(const Key& k) const {
            return findHelp(root, k);
        }
    
        // Return the number of records in the dictionary
        int size() {
            return nodeCount;
        }
    
        // Print the contents of the BST
        void print() const {
            if (root == NULL) {
                cout << "The BST is empty.
    ";
            }
            else {
                printHelp(root, 0);
            }
        }
    };
    
    template <typename Key, typename E>
    E BST<Key, E>::findHelp(BSTNode<Key, E>* root, const Key& k) const {
        if (root == NULL) return NULL;
        if (k < root->key()) {
            return findHelp(root->left(), k);
        }
        else if (k > root->key()) {
            return findHelp(root->right(), k);
        }
        else {
            return root->element();
        }
    }
    
    template <typename Key, typename E>
    BSTNode<Key, E>* BST<Key, E>::insertHelp(BSTNode<Key, E>* root, const Key& k, const E& it) {
        if (root == NULL) {
            return new BSTNode<Key, E>(k, it, NULL, NULL);
        }
        if (k < root->key()) {
            root->setLeft(insertHelp(root->left(), k, it));
        }
        else {
            root->setRight(insertHelp(root->right(), k, it));
        }
        return root;    // return tree with node inserted
    }
    
    template <typename Key, typename E>
    BSTNode<Key, E>* BST<Key, E>::deleteMin(BSTNode<Key, E>* rt) {
        if (rt->left() == NULL) {
            return rt->right();
        }
        else {
            rt->setLeft(deleteMin(rt->left()));
            return rt;
        }
    }
    
    template <typename Key, typename E>
    BSTNode<Key, E>* BST<Key, E>::getMin(BSTNode<Key, E>* rt) {
        if (rt->left() == NULL) {
            return rt;
        }
        else {
            return getMin(rt->left());
        }
    }
    
    template <typename Key, typename E>
    BSTNode<Key, E>* BST<Key, E>::removeHelp(BSTNode<Key, E>* rt, const Key& k) {
        if (rt == NULL) {
            return NULL;
        }
        else if (k < rt->key()) {
            rt->setLeft(removeHelp(rt -> left(), k));
        }
        else if (k > rt->key()) {
            rt->setRight(removeHelp(rt->right(), k));
        }
        else {
            BSTNode<Key, E>* temp = rt;
            if (rt->left() == NULL) {
                rt = rt->right();
                delete temp;
            }
            else if (rt->right() == NULL) {
                rt = rt->left();
                delete temp;
            }
            else {
                BSTNode<Key, E>* temp = getMin(rt->right());
                rt->setElement(temp->element());
                rt->setKey(temp->key());
                rt->setRight(deleteMin(rt->right()));
                delete temp;
            }
        }
        return rt;
    }
    
    template <typename Key, typename E>
    void BST<Key, E>::clearHelp(BSTNode<Key, E>* root) {
        if (root == NULL) return;
        clearHelp(root->left());
        clearHelp(root->right());
        delete root;
    }
    
    template <typename Key, typename E>
    void BST<Key, E>::printHelp(BSTNode<Key, E>* root, int level) const {
        if (root == NULL) {
            return;
        }
        printHelp(root->left(), level + 1);
        for (int i = 0; i < level; i++) {
            cout << " ";
        }
        cout << < root->key() << "
    ";
        printHelp(root->right(), level + 1);
    }

    其中字典类的声明

    template <typename Key, typename E>
    class Dictionary {
    private:
        void operator = (const Dictionary&) {}
        Dictionary(const Dictionary&) {}
    public:
        Dictionary() {}            // Default constructor.
        virtual ~Dictionary() {}    // Base destructor.
    
        // Reinitialize dictionary.
        virtual void clear() = 0;
    
        // Insert a record.
        // k:The key for the record being inserted.
        // e:The record being inserted.
        virtual void insert(const Key& k, const E& e) = 0;
    
        // Remove and return a record.
        // k: The key of the record to be removed.
        // Return: A maching record. If multiple records match.
        // "k", remove an arbitrary one. Return NULL if no record.
        // with key "k" exists.
        virtual E remove(const Key& k) = 0;
    
        // Remove and return an arbitrary record from dictionary.
        // Return: The record removed, or NULL if none exists.
        virtual E removeAny() = 0;
    
        // Return: A record matching "k" (NULL if none exists).
        // If multiple records match, return an arbitrary one.
        // k: The key of the record to find.
        virtual E find(const Key& k) const = 0;
    
        // Return the number of records in the dictionary.
        virtual int size() = 0;
    };
  • 相关阅读:
    python3 socketserver服务端
    python3 组合的用法
    python3 面向对象高级一些的
    python3 继承原理
    python3 对象之间的交互
    hadoop配置、运行错误总结
    Hadoop配置项整理(mapred-site.xml)
    Hadoop配置项整理(core-site.xml)
    Hadoop配置项整理(hdfs-site.xml)
    Linux Shell 按Tab键不能补全
  • 原文地址:https://www.cnblogs.com/feng-ying/p/10530314.html
Copyright © 2011-2022 走看看