/*
二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有节点的值均小于它的根节点的值;
(2)若右子树不空,则右子树上所有节点的值均大于它的根节点的值;
(3)左、右子树也分别为二叉排序树;
(4)没有键值相等的节点。
*/
#include <iostream>
#include <algorithm>
#include <ctime>
#include <list>
using namespace std;
struct BinaryData
{
BinaryData() :m_data(0){}
BinaryData(int a) :m_data(a){}
friend bool operator>(BinaryData a, BinaryData b)
{
return a.m_data > b.m_data;
}
int m_data;
};
struct BinaryNode
{
BinaryNode(){
memset(this, 0, sizeof(*this));
}
BinaryNode * lChrild;
BinaryNode * rChrild;
BinaryNode * father;
BinaryData data;
int nCount;
};
class BinaryTree
{
public:
BinaryTree();
~BinaryTree();
public:
bool DeleteRoot(BinaryNode * &);
bool InsertNode(BinaryData *);
BinaryNode * FindComNode(BinaryNode *, BinaryData*);
void FindNode(BinaryNode *&, BinaryData*, BinaryNode *&);
bool DeleteOneNode(BinaryData *);
bool DeleteAllNode(BinaryData *);
public:
BinaryNode *node;
int nNodeCount;
};
BinaryTree::BinaryTree()
{
nNodeCount = 0;
node = NULL;
}
BinaryTree::~BinaryTree()
{
if (nNodeCount > 0)
{
DeleteRoot(node->lChrild);
DeleteRoot(node->rChrild);
}
}
bool BinaryTree::DeleteRoot(BinaryNode * &n)
{
if (n == NULL) return false;
if (n->lChrild == NULL && n->rChrild == NULL)
{
delete n;
n = NULL;
}
else{
DeleteRoot(n->lChrild);
DeleteRoot(n->rChrild);
delete n;
n = NULL;
}
return true;
}
bool BinaryTree::InsertNode(BinaryData *b)
{
//没有元素
if (nNodeCount == 0)
{
//插入根节点
node = new BinaryNode;
node->data = *b;
}
else{
//是否已经有元素存在
BinaryNode *has = NULL;
FindNode(node, b, has);
//插入相同元素
if (has != NULL)
{
//元素个数+1;
has->nCount++;
nNodeCount++;
return true;
}
//是新元素 查找插入位置的父节点
BinaryNode *root = FindComNode(node, b);
if (root != NULL)
{
BinaryNode *temp = new BinaryNode;
temp->data = *b;
if ((*b) > root->data )
{
root->rChrild = temp;
}
else{
root->lChrild = temp;
}
temp->father = root;
temp->nCount++;
nNodeCount++;
return true;
}
return false;
}
nNodeCount++;
return true;
}
BinaryNode * BinaryTree::FindComNode(BinaryNode * n,BinaryData* b)
{
if ((*b) > n->data )
{
if (n->rChrild == NULL)
{
return n;
}
else{
return FindComNode(n->rChrild, b);
}
}
else{
if (n->lChrild == NULL)
{
return n;
}
else{
return FindComNode(n->lChrild, b);
}
}
}
void BinaryTree::FindNode(BinaryNode *&root, BinaryData* b, BinaryNode *&result)
{
if (root == NULL )
return ;
if ((root)->data.m_data == b->m_data)
{
result = root;
}
else if ((root)->data.m_data > b->m_data)
{
FindNode((root)->lChrild, b, result);
}
else{
FindNode((root)->rChrild, b, result);
}
}
//获得遍历列表
void GetSearchList(BinaryNode *root, list<BinaryNode *> &tempList)
{
if (root == NULL) return;
GetSearchList(root->lChrild, tempList);
tempList.push_back(root);
GetSearchList(root->rChrild, tempList);
}
//删除所有b元素
bool BinaryTree::DeleteAllNode(BinaryData *b)
{
BinaryNode * root = NULL;
//寻找是否b节点
FindNode(node, b, root);
if (root == NULL) return false;
//删除元素个数
int nCount = root->nCount;
//删除节点左子树为空
if (root->lChrild == NULL)
{
//有父节点
if (root->father)
{
//父节点指向当前节点右子树
if (root->father->lChrild == root)
{
root->father->lChrild = root->rChrild;
}
else{
root->father->rChrild = root->rChrild;
}
}
else{
//没有父节点 是根节点
node = root->rChrild;
}
//当前节点有右子树
if (root->rChrild)
{
//右子树指向 当前节点的父节点
root->rChrild->father = root->father;
}
//删除当前节点
delete root;
root = NULL;
}
//删除节点右子树为空 左子树一定不为空
else if (root->rChrild == NULL)
{
//有父节点
if (root->father)
{
//父节点指向左子树
if (root->father->lChrild == root)
{
root->father->lChrild = root->lChrild;
}
else{
root->father->rChrild = root->lChrild;
}
}
else{
//没有父节点 是根节点
node = root->lChrild;
}
//左子树不会为空
//if (root->lChrild)
{
root->lChrild->father = root->father;
}
//删除当前节点
delete root;
root = NULL;
}
else{
//寻找当前节点的前驱
BinaryNode * before = root->lChrild;
while (before->rChrild)
{
before = before->rChrild;
}
//将前驱数据与当前节点交换 此时要删除的节点变为前驱节点
root->data.m_data = before->data.m_data;
root->nCount = before->nCount;
//前驱节点的父节点指向 前驱的左子树(可能为空) 注意前驱没有右子树
if (before->father->rChrild == before)
before->father->rChrild = before->lChrild;
else if (before->father->lChrild == before)
{
before->father->lChrild = before->lChrild;
}
//如果有左子树 将左字数父节点指向 前驱的父节点
if (before->lChrild)
{
before->lChrild->father = before->father;
}
//删除前驱节点
delete before;
before = NULL;
}
nNodeCount -= nCount;
return true;
}
bool BinaryTree::DeleteOneNode(BinaryData *b)
{
BinaryNode * root = NULL;
//寻找是否b节点
FindNode(node, b, root);
if (root == NULL) return false;
int nCount = root->nCount;
//元素个数减1
root->nCount--;
nNodeCount--;
//元素个数为0 删除节点
if (root->nCount == 0)
{
DeleteAllNode(b);
}
return true;
}
void Print(BinaryNode *t)
{
if (t == NULL) return;
Print(t->lChrild);
for (int i = 0; i < t->nCount; i++)
{
cout << t->data.m_data << " ";
}
Print(t->rChrild);
}
int RAND(int a)
{
return rand() % a;
}
int main()
{
srand(time(NULL));
int a[30] = {};
BinaryTree bt;
while (true)
{
for (int i = 20; i >= 1; i--)
{
a[i] = RAND(20) + 1;
}
random_shuffle(a + 1, a + 21, RAND);
for (int i = 20; i >= 1; i--)
{
bt.InsertNode(&BinaryData(a[i]));
}
Print(bt.node);
cout << endl;
random_shuffle(a + 1, a + 21, RAND);
for (int i = 20; i >= 1; i--)
{
cout << "Delete " << a[i] << endl;
bt.DeleteOneNode(&BinaryData(a[i]));
Print(bt.node);
cout << endl;
}
Print(bt.node);
cout << endl;
}
return 0;
}