/*构造有序二叉树,插入元素并遍历打印
* 要求左子树大于根节点大于右子树
*二叉树特点:有且仅有一个根节点
*每个根节点只有一个直接前驱和最多两个直接后继
*/
#include <iostream>
using namespace std;
class Tree {
//树的辅助结构体,一个节点包括数据和指向左右子树的两个指针
struct Node {
int data;
Node* left;
Node* right;
};
public:
//无参构造函数(构造一棵空树)
Tree() : root(NULL) { }
//插入节点
Tree& Add(const int& data)
{
add(root, data);
return *this;
}
//查找节点
bool Search(const int& data)
{
Node* p = root;
while (p != NULL) {
if (data < p->data) {
p = p->left;
} else if (data > p->data) {
p = p->right;
} else {
return true;
}
}
return false;
}
//删除节点
Tree& Remove(const int& data)
{
Node* p = root;
Node* parent = NULL;
//1.找到该节点,并保存其父节点
while (p != NULL) {
if (data < p->data) {//数据比根节点小,则在根节点左侧
parent = p;//父节点指向p
p = p->left;//p指向p的左子树
} else if (data > p->data) { //数据比根节点大,同理
parent = p;
p = p->right;
} else { //数据和根节点相等
break;
}
}
//2.将其父节点和子节点重新链接
//2.1 空二叉树
if (p == NULL) {//空二叉树,无需处理
return *this;
}
//2.2左右子树为空
if (p->left==NULL && p->right==NULL) {
if (p == root) { //如果p是根节点
root = NULL;//将根节点置空
} else if (data < parent->data) { //如果p是左子树
parent->left = NULL;//将左子树置空
} else { //p是右子树
parent->right= NULL;//将右子树置空
}
}
//2.3 左子树不为空,右子树为空
else if (p->left!=NULL && p->right==NULL) {
if (p == root) {
root = p->left;
} if (data < parent->data) {
parent->left = p->left;
} else {
parent->right= p->left;
}
}
//2.4左子树为空,右子树不为空
else if (p->left==NULL && p->right!=NULL) {
if (p == root) {
root = p->right;
} if (data < parent->data) {
parent->left = p->right;
} else {
parent->right= p->right;
}
}
//2.5左右子树都不为空
else if (p->left!=NULL && p->right!=NULL) {
if (p == root) { //如果要删除的是根节点,
root = p->right;
} else if (data < parent->data) {//如果要删除的是左子树
parent->left = p->right;
} else {
parent->right= p->right;
}
Node* t = p->right;//因为删除任意一个节点,其位置都会由其右子树继承,保存p的右子树,将p的左子树链接到右子树的尾节点
while (t->left != NULL) {
t = t->left;
}
t->left = p->left;
}
delete p; //删除p并释放p的内存
return *this;
}
//打印二叉树
Tree& Print()
{
print(root);
printf("\n");
return *this;
}
private:
//打印二叉树,外部不可访问
void print(Node* p)
{
if (p != NULL) {
print(p->left);
printf("%d ", p->data);
print(p->right);
}
}
//添加节点,外部不可访问,保证二叉树安全,递归添加
void add(Node*& p, const int& data)
{
if (p == NULL) { //p为空,添加的节点即根节点,其左右子树为空
p = new Node;
p->data = data;
p->left = NULL;
p->right= NULL;
} else if (data < p->data) //如果数据比父节点小,作为父节点的左子树
{
add(p->left, data);
} else if (data > p->data) //如果数据比父节点大,作为父节点的右子树
{
add(p->right,data);
}
}
Node* root;
};
int main()
{
Tree t;
t.Add(30);
t.Add(20).Add(10).Add(25).Add(21);
t.Add(40).Add(80).Add(70).Add(90);
cout << "打印二叉树 : "<<endl;
t.Print();
cout << "40是否在二叉树中 : "<<endl;
cout << t.Search(40) << endl;
cout << "删除30 : "<<endl;
t.Remove(30).Print();
}
* 要求左子树大于根节点大于右子树
*二叉树特点:有且仅有一个根节点
*每个根节点只有一个直接前驱和最多两个直接后继
*/
#include <iostream>
using namespace std;
class Tree {
//树的辅助结构体,一个节点包括数据和指向左右子树的两个指针
struct Node {
int data;
Node* left;
Node* right;
};
public:
//无参构造函数(构造一棵空树)
Tree() : root(NULL) { }
//插入节点
Tree& Add(const int& data)
{
add(root, data);
return *this;
}
//查找节点
bool Search(const int& data)
{
Node* p = root;
while (p != NULL) {
if (data < p->data) {
p = p->left;
} else if (data > p->data) {
p = p->right;
} else {
return true;
}
}
return false;
}
//删除节点
Tree& Remove(const int& data)
{
Node* p = root;
Node* parent = NULL;
//1.找到该节点,并保存其父节点
while (p != NULL) {
if (data < p->data) {//数据比根节点小,则在根节点左侧
parent = p;//父节点指向p
p = p->left;//p指向p的左子树
} else if (data > p->data) { //数据比根节点大,同理
parent = p;
p = p->right;
} else { //数据和根节点相等
break;
}
}
//2.将其父节点和子节点重新链接
//2.1 空二叉树
if (p == NULL) {//空二叉树,无需处理
return *this;
}
//2.2左右子树为空
if (p->left==NULL && p->right==NULL) {
if (p == root) { //如果p是根节点
root = NULL;//将根节点置空
} else if (data < parent->data) { //如果p是左子树
parent->left = NULL;//将左子树置空
} else { //p是右子树
parent->right= NULL;//将右子树置空
}
}
//2.3 左子树不为空,右子树为空
else if (p->left!=NULL && p->right==NULL) {
if (p == root) {
root = p->left;
} if (data < parent->data) {
parent->left = p->left;
} else {
parent->right= p->left;
}
}
//2.4左子树为空,右子树不为空
else if (p->left==NULL && p->right!=NULL) {
if (p == root) {
root = p->right;
} if (data < parent->data) {
parent->left = p->right;
} else {
parent->right= p->right;
}
}
//2.5左右子树都不为空
else if (p->left!=NULL && p->right!=NULL) {
if (p == root) { //如果要删除的是根节点,
root = p->right;
} else if (data < parent->data) {//如果要删除的是左子树
parent->left = p->right;
} else {
parent->right= p->right;
}
Node* t = p->right;//因为删除任意一个节点,其位置都会由其右子树继承,保存p的右子树,将p的左子树链接到右子树的尾节点
while (t->left != NULL) {
t = t->left;
}
t->left = p->left;
}
delete p; //删除p并释放p的内存
return *this;
}
//打印二叉树
Tree& Print()
{
print(root);
printf("\n");
return *this;
}
private:
//打印二叉树,外部不可访问
void print(Node* p)
{
if (p != NULL) {
print(p->left);
printf("%d ", p->data);
print(p->right);
}
}
//添加节点,外部不可访问,保证二叉树安全,递归添加
void add(Node*& p, const int& data)
{
if (p == NULL) { //p为空,添加的节点即根节点,其左右子树为空
p = new Node;
p->data = data;
p->left = NULL;
p->right= NULL;
} else if (data < p->data) //如果数据比父节点小,作为父节点的左子树
{
add(p->left, data);
} else if (data > p->data) //如果数据比父节点大,作为父节点的右子树
{
add(p->right,data);
}
}
Node* root;
};
int main()
{
Tree t;
t.Add(30);
t.Add(20).Add(10).Add(25).Add(21);
t.Add(40).Add(80).Add(70).Add(90);
cout << "打印二叉树 : "<<endl;
t.Print();
cout << "40是否在二叉树中 : "<<endl;
cout << t.Search(40) << endl;
cout << "删除30 : "<<endl;
t.Remove(30).Print();
}