包含所有的二叉搜索树的接口实现。后面博客会陆续写出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;
}
}
}
最后会进行整合。喜欢请关注,有问题留言,看到会回复。