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; };