// 左孩子< 父节点 < 右孩子,不是二叉平衡树
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// 管理节点
typedef struct BstNode
{
int data;
struct BstNode *lchild;
struct BstNode *rchild;
} BstNode;
#define NODE BstNode
#include "drawtree.h"
// 初始化节点
BstNode *init_node(int data)
{
BstNode *p = malloc(sizeof(BstNode));
if (p == NULL)
{
return NULL;
}
p->data = data;
p->lchild = NULL;
p->rchild = NULL;
return p;
}
// 插入节点
BstNode *insert_node(BstNode *root, int data)
{
BstNode *pnew = init_node(data); // 为新节点初始化
if (pnew == NULL)
{
return NULL;
}
// 寻找在哪里插入新节点
BstNode *p = root;
if (root == NULL) // 如果根节点为空,插入根节点
{
root = pnew;
}
else
{
while (1) // 循环查找叶子节点,然后插入
{
if (data > p->data)
{
if (p->rchild == NULL)
{
p->rchild = pnew;
break;
}
else
{
p = p->rchild;
}
}
else if (data < p->data)
{
if (p->lchild == NULL)
{
p->lchild = pnew;
break;
}
else
{
p = p->lchild;
}
}
else
{
printf("该数已经插入树中,无法重复插入\n");
}
}
}
return root;
}
// 创建一个树
BstNode *create_BstTree()
{
BstNode *root = NULL; // 刚开始根节点为空,这时还没有为root开辟空间
int data; // 插入节点的值,等会自己赋值
// 开始循环赋值,输入非数字的会结束建树
while (1)
{
if (0 == scanf("%d", &data)) // 判断结束条件
{
while (getchar() != '\n') // 取走缓冲区的字符
;
break;
}
root = insert_node(root, data); // 插入节点后需要跟新,所以用root接受
}
return root;
}
// 前序
void pre_order(BstNode *root)
{
if (root == NULL)
{
return;
}
// 跟左右
printf("%d\t", root->data);
pre_order(root->lchild);
pre_order(root->rchild);
}
// 中序
void mid_order(BstNode *root)
{
if (root == NULL)
{
return;
}
// 左根右
mid_order(root->lchild);
printf("%d\t", root->data);
mid_order(root->rchild);
}
// 后序
void post_order(BstNode *root)
{
if (root == NULL)
{
return;
}
// 左右根
post_order(root->lchild);
post_order(root->rchild);
printf("%d\t", root->data);
}
// 递归删除节点
BstNode *remove_node(BstNode *root, int data)
{
if (root == NULL)
{
return NULL;
}
if (root->data > data) // 如果小于要删除的数,进入该节点的左孩子,继续调用remove()函数
{
root->lchild = remove_node(root->lchild, data);
}
else if (root->data < data) // 大于......
{
root->rchild = remove_node(root->rchild, data);
}
else // 找到要删除的节点
{
if (root->lchild != NULL) // 只有左
{
BstNode *p = NULL;
for (p = root->lchild; p->rchild != NULL; p = p->rchild) // 找左子树的最大值
;
root->data = p->data;
root->lchild = remove_node(root->lchild, p->data);
}
else if (root->rchild != NULL) // 只有右
{
BstNode *p = NULL;
for (p = root->rchild; p->lchild != NULL; p = p->lchild) // 找右子树的最小值
;
root->data = p->data;
root->rchild = remove_node(root->rchild, p->data);
}
else // 叶子节点
{
free(root);
return NULL;
}
}
return root;
}
int main(int argc, char const *argv[])
{
BstNode *root = create_BstTree();
if (root == NULL)
{
printf("建树失败\n");
return -1;
}
// 前,中,后序遍历
pre_order(root);
// mid_order(root);
// post_order(root);
printf("\n");
// 递归删除节点
root = remove_node(root, 10);
draw(root); // 画图用的,可以删掉,不能直接用,没有头文件用不了
pre_order(root);
return 0;
}