二叉树

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;
};
原文地址:https://www.cnblogs.com/feng-ying/p/10530314.html