二分查找樹特色:node
(1) 若任意節點的左子樹不空,則左子樹上全部結點的值均小於它的根結點的值;ios
(2) 任意節點的右子樹不空,則右子樹上全部結點的值均大於它的根結點的值;ide
(3) 任意節點的左、右子樹也分別爲二叉查找樹。post
(4) 沒有鍵值相等的節點(no duplicate nodes)。spa
前序遍歷:中左右3d
中序遍歷:左中右code
序遍歷:左右中blog
二叉查找樹的重點在於如何找節點的前驅節點和後繼節點排序
#pragma once #include <iostream> using namespace std; template <class T> class BSTNode { public: T key; BSTNode *parent; BSTNode *left; BSTNode *right; BSTNode(T value, BSTNode *p, BSTNode *l, BSTNode *r):key(value),parent(p),left(l),right(r) { } }; template <class T> class BSTree { private: BSTNode<T> *mRoot; public: BSTree():mRoot(NULL){} ~BSTree(){} // 前序排序 void preOrder() { preOrder(mRoot); } void inOrder() { inOrder(mRoot); } void postOrder() { postOrder(mRoot); } // 查找二叉樹中鍵值爲key的節點 BSTNode<T>* SearchKey(const T key) { return SearchKey(mRoot, key); } BSTNode<T>* minKey() { return minKey(mRoot); } BSTNode<T>* maxKey() { return maxKey(mRoot); } // 插入節點 void insert( T key) { BSTNode<T> *z = new BSTNode<T>(key, NULL, NULL, NULL); if (z == NULL) { return; } insert(mRoot, z); } private: // 前序排序 void preOrder(BSTNode<T> *tree) const { if (tree != NULL) { cout << tree->key << " "; preOrder(tree->left); preOrder(tree->right); } } // 中序排序 void inOrder(BSTNode<T> *tree) const { if (tree != NULL) { preOrder(tree->left); cout << tree->key << " "; preOrder(tree->right); } } // 後序排序 void postOrder(BSTNode<T> *tree) const { if (tree != NULL) { preOrder(tree->left); preOrder(tree->right); cout << tree->key << " "; } } BSTNode<T>* SearchKey(BSTNode<T>* pNode, const T key) const { // 遞歸查找 /*if (pNode = NULL || key == pNode->key) { return pNode; } else if (key > pNode->key) { return SearchKey(pNode->right); } else { return SearchKey(pNode->left); }*/ // 非遞歸查找 BSTNode<T>* x = pNode; while (x != NULL) { if (key > x->key) { x = x->right; } else if (key < x->key) { x = x->left; } else { return x; } } return NULL; } // 將節點插入到二叉樹中 void insert(BSTNode<T>* &tree, BSTNode<T> *Node) { BSTNode<T> *y = NULL; BSTNode<T> *x = tree; while (NULL != x) { y = x; if (Node->key > x->key) { x = x->right; } else { x = x->left; } } Node->parent = y; // 這到後面兩句爲關鍵代碼 if (NULL == y) { tree = Node; } else if (Node->key > y->key) { y->right = Node; } else { y->left = Node; } } // 查找最小節點 BSTNode<T>* minKey(BSTNode<T>* pNode) const { while (pNode != NULL) { pNode = pNode->left; } return pNode; } BSTNode<T>* maxKey(BSTNode<T>* pNode) const { while (pNode != NULL) { pNode = pNode->right; } return pNode; } // 找節點(x)的後繼節點。即查找二叉樹中數值大於該節點的最小值 BSTNode<T>* Successor(BSTNode<T>* x) { // 分三種狀況 // 1. x有右孩子,找到以右孩子爲根的子樹的最小節點 // 2. x沒有右孩子,當x爲左孩子,則x的父節點爲後繼節點 // 2. x沒有右孩子,當x爲右孩子,則找x的最低父節點,而且該父節點具備左孩子 if (x->right != NULL) { return minKey(x->right); } BSTNode<T>* y = x->parent; while ((NULL != y) &&(x == y->right)) { x= y; y = y->parent; } return y; } // 找結點(x)的前驅結點。即查找"二叉樹中數據值小於該結點"的"最大結點" BSTNode<T>* BSTree<T>::predecessor(BSTNode<T> *x) { // 若是x存在左孩子,則"x的前驅結點"爲 "以其左孩子爲根的子樹的最大結點"。 if (x->left != NULL) return maxKey(x->left); // 若是x沒有左孩子。則x有如下兩種可能: // (01) x是"一個右孩子",則"x的前驅結點"爲 "它的父結點"。 // (01) x是"一個左孩子",則查找"x的最低的父結點,而且該父結點要具備右孩子",找到的這個"最低的父結點"就是"x的前驅結點"。 BSTNode<T>* y = x->parent; while ((y!=NULL) && (x==y->left)) { x = y; y = y->parent; } return y; } // 刪除二叉樹中的節點,並返回被刪除的節點 //BSTNode<T>* RemoveNode(BSTNode<T>* &tree, BSTNode<T>* pNode) //{ // BSTNode<T>* x = tree; // while (NULL != x && pNode->key != x->key) // { // if (pNode->key > x->key) // { // x = x->right; // } // else if (pNode->key < x->key) // { // x = x->left; // } // } // // 找到或x爲空 //} };