包含所有的二叉搜索樹的接口實現。後面博客會陸續寫出AVL樹,B樹,紅黑樹。
接口API的定義:
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>//輸入輸出流的庫
using namespace std;
#include <queue>
#include <string>
class BinarySearchTree
{
private:
class Node
{
public:
int element;
Node * left;
Node * right;
Node * parent;
public:
Node(int element, Node * parent);
public:
bool isLeaf();
public:
bool hasTwoChildren();
};
private:
int m_size;
Node * root;
public:
BinarySearchTree();
~BinarySearchTree();
public:
int size();
bool isEmpty();
void clear();
void add(int element);
bool contains(int element);
void preorderTravelsal();
void inorderTravelsal();
void postorderTravelsal();
void levelorderTravelsal();
private:
void postorderTravelsal(Node * node);
private:
void inorderTravelsal(Node * node);
private:
void preorderTravelsal(Node * node);
private:
void elementNotNULLCheck(int element);
private:
//返回=0 代表e1等於e2
//返回>0 代表e1大於e2
//返回<0 代表e1小於e2
int compare(int e1, int e2);
public:
void toString();
private:
void toString(Node * node,string sb, string prefix);
public:
int height();
private:
int height(Node * node);
public:
int height2();
public:
bool isComplete();
public:
void * predecessor(Node * node);
public:
void * sucessor(Node * node);
public:
void remove(int element);
private:
void * node(int element);
private:
void remove(Node * node);
};
接口的實現:
#include "BinarySearchTree.h"
BinarySearchTree::Node::Node(int element, Node * parent)
{
this->element = element;
this->parent = parent;
}
bool BinarySearchTree:: Node::isLeaf()
{
return left == NULL && right == NULL;
}
//前驅結點
void * BinarySearchTree::predecessor(Node * node)
{
if (node == NULL)
{
return NULL;
}
//前驅結點在左子樹中 (left->right->right->...)
if (node->left != NULL)
{
Node * p = node->left;
while (p->right != NULL)
{
p = p->right;
}
return (void *)p;
}
//
while (node->parent != NULL && node == node->parent->left)
{
node = node->parent;
}
//node->parent == NULL;
//node == node->parent->right;
return (void*)node->parent;
}
//後繼結點
void * BinarySearchTree::sucessor(Node * node)
{
if (node == NULL)
{
return NULL;
}
//前驅結點在左子樹中 (right->left->left->...)
if (node->right != NULL)
{
Node * p = node->left;
while (p->left != NULL)
{
p = p->left;
}
return (void *)p;
}
//
while (node->parent != NULL && node == node->parent->right)
{
node = node->parent;
}
//node->parent == NULL;
//node == node->parent->right;
return (void*)node->parent;
}
bool BinarySearchTree::Node::hasTwoChildren()
{
return left != NULL && right != NULL;
}
BinarySearchTree::BinarySearchTree()
{
this->m_size = 0;
}
BinarySearchTree::~BinarySearchTree()
{
}
int BinarySearchTree::size()
{
return this->m_size == 0;
}
bool BinarySearchTree::isEmpty()
{
return root->element == NULL;
}
void BinarySearchTree::clear()
{
this->root = NULL;
this->m_size = 0;
return;
}
void BinarySearchTree::add(int element)
{
this->elementNotNULLCheck(element);
if (this->root == NULL)
{
//添加第一個結點
root = new Node(element, NULL);
this->m_size++;
return;
}
//添加的不是根節點
//找到父節點
Node * parent = this->root;
Node * node = this->root;
int cmp = 0;
while (node != NULL)
{
cmp = compare(element, node->element);
//保存父節點
parent = node;
if (cmp > 0)
{
node = node->right;
}
else if (cmp < 0)
{
node = node->left;
}
else //相等
{
node->element = element;
return;
}
}
//看看插入到父節點的哪個位置
Node * newnode = new Node(element, parent);
if (cmp > 0)
{
parent->right = newnode;
}
else if (cmp < 0)
{
parent->left = newnode;
}
this->m_size++;
return ;
}
void BinarySearchTree::remove(int element)
{
remove((Node*)node(element));
}
void * BinarySearchTree::node(int element)
{
Node * node = this->root;
while (node != NULL)
{
int cmp = this->compare(element, node->element);
if (cmp == 0)
{
return (void*)node;
}
else if (cmp > 0)
{
node = node->right;
}
else//element < node->element
{
node = node->left;
}
}
return NULL;
}
void BinarySearchTree::remove(Node * node)
{
if (node == NULL)
{
return;
}
this->m_size--;
if (node->hasTwoChildren()) //度爲2
{
//找到後繼結點
Node * s = (Node*)this->sucessor(node);
//用後繼結點的值覆蓋度爲2的結點
node->element = s->element;
//刪除後繼結點
node = s;//????
}
//刪除node結點(node的結點 度必然是0或者1)
Node * replacement = node->left != NULL ? node->left : node->right;
if (replacement != NULL)//度爲1
{
//更改parent
replacement->parent = node->parent;
//更改parent的left,right的指向
if (node->parent == NULL)
{
//node是度爲1的結點並且是根節點
this->root = replacement;
}
else if (node == node->parent->left)
{
node->parent->left = replacement;
}
else if(node == node->parent->right)
{
node->parent->right = replacement;
}
}
else if(node->parent == NULL)//度爲0,即葉子結點.又是根節點
{
this->root == NULL;
}
else //度爲0,即葉子結點,但不是根節點
{
if (node == node->parent->right)
{
node->parent->right = NULL;
}
else
{
node->parent->left = NULL;
}
}
}
bool BinarySearchTree::contains(int element)
{
return node(element) != NULL;
}
void BinarySearchTree::elementNotNULLCheck(int element)
{
if (element == NULL)
{
printf("fun elementNotNULLCheck() err\n");
return;
}
}
//返回=0 代表e1等於e2
//返回>0 代表e1大於e2
//返回<0 代表e1小於e2
int BinarySearchTree::compare(int e1, int e2)
{
if (e1 == e2)
{
return 0;
}
else if (e1 > e2)
{
return 1;
}
else
{
return -1;
}
}
void BinarySearchTree::inorderTravelsal()
{
inorderTravelsal(this->root);
}
void BinarySearchTree::inorderTravelsal(Node * node)
{
if (node == NULL)
{
return;
}
inorderTravelsal(node->left);
cout << node->element << " ";
inorderTravelsal(node->right);
}
void BinarySearchTree::postorderTravelsal()
{
postorderTravelsal(this->root);
}
void BinarySearchTree::postorderTravelsal(Node * node)
{
if (node == NULL)
{
return;
}
postorderTravelsal(node->left);
postorderTravelsal(node->right);
cout << node->element << " ";
}
void BinarySearchTree::levelorderTravelsal()
{
if (this->root == NULL)
{
return;
}
queue<Node*> queue;
queue.push(root);
while (!queue.empty())
{
Node * node = queue.front();
queue.pop();
cout << node->element << " ";
if (node->left != NULL)
{
queue.push(node->left);
}
if (node->right != NULL)
{
queue.push(node->right);
}
}
}
void BinarySearchTree::toString()
{
string sb;
toString(this->root,sb,"");
}
void BinarySearchTree::toString(Node * node,string sb,string prefix)
{
if (node == NULL)
{
return;
}
cout << prefix<<node->element << endl;
toString(node->left,sb, prefix +"L--");
toString(node->right,sb, prefix+"R--");
}
void BinarySearchTree::preorderTravelsal()
{
preorderTravelsal(this->root);
}
void BinarySearchTree::preorderTravelsal(Node * node)
{
if (node == NULL)
{
return;
}
toString();
cout << node->element << " ";
preorderTravelsal(node->left);
preorderTravelsal(node->right);
}
int BinarySearchTree::height()
{
return height(this->root);
}
int BinarySearchTree::height(Node * node)
{
if (node == NULL)
{
return 0;
}
return 1 + (int)max(height(node->left), height(node->right));
}
int BinarySearchTree::height2()
{
if (this->root == NULL)
{
return 0;
}
queue<Node*> queue;
queue.push(root);
int rowsize = 1;
//樹的高度
int height = 0;
while (!queue.empty())
{
Node * node = queue.front();
queue.pop();
rowsize--;
if (node->left != NULL)
{
queue.push(node->left);
}
if (node->right != NULL)
{
queue.push(node->right);
}
if (rowsize == 0) //意味着即將訪問下一層
{
rowsize = queue.size();
height++;
}
}
return height;
}
bool BinarySearchTree::isComplete()
{
if (this->root == NULL)
{
return 0;
}
queue<Node*> queue;
queue.push(root);
bool leaf = false;
while (!queue.empty())
{
Node * node = queue.front();
queue.pop();
if (leaf && !node->isLeaf())
{
return false;
}
if (node->left != NULL)
{
queue.push(node->left);
}
else if(node->right != NULL)
{
//node->left == NULL && node->right != NULL
return false;
}
if (node->right != NULL)
{
queue.push(node->right);
}
else
{
//node->left == NULL && node->right == NULL
//node->left != NULL && node->right == NULL
//葉子結點
leaf = true;
}
}
}
最後會進行整合。喜歡請關注,有問題留言,看到會回覆。