///此处省去概念若干字~ 欢迎指错
#include <iostream>
#include<queue>
using namespace std;
typedef struct treenode
{
int data;
treenode *lchild;
treenode *rchild;
}node;
int flag = -1;
void insert_node(node* root, node* child)
{
///要插的子树不为空
if(root->data >= child->data && root->lchild != NULL)
{
insert_node(root->lchild, child);
return;
}
if(root->data < child->data && root->rchild != NULL)
{
insert_node(root->rchild, child);
return ;
}
///要插的子树为空 刚好可以插入
if(root->data >= child->data && root->lchild == NULL)///一定要注意这两种情况的先后顺序
root->lchild = child;
if(root->data < child->data && root->rchild == NULL)///我刚开始就写反了 程序就崩了
root->rchild = child; ///因为下面这种情况执行之后 孩子就不空了 那么第二个条件
} ///就一定成立了 然后就悲催的死循环了
void createTree(node **root, int *arr, int n)///建树
{
(*root) = new node;
(*root)->data = arr[0];
(*root)->lchild = NULL;
(*root)->rchild = NULL;
node *child;
for(int i=1; i<n; i++)
{
child = new node;
child->data = arr[i];
child->lchild = NULL;
child->rchild = NULL;
insert_node(*root, child);
}
}
void in(node *root)
{
if(root)
{
if(root->lchild)
in(root->lchild);
cout << root->data << ' ';
if(root->rchild)
in(root->rchild);
}
}
void print(int *arr, int n)
{
for(int i=0; i<n; i++)
{
cout << arr[i] <<' ';
}
}
node* search_node(node *root, int e)///找值为X的节点
{
queue<node *>q;
node *a;
if(root)
{
while(!q.empty())
q.pop();
q.push(root);
while(!q.empty())
{
a = q.front();
q.pop();
if(a->data == e)
{
return a;
}
else
{ ///注意啦注意啦 在对节点 或者 他的左右孩子做什么操作之前 尽量判断一下他是不是空的
if(a->lchild)/// 卡在这好一会啊
q.push(a->lchild);
if(a->rchild)
q.push(a->rchild);
}
}
}
return NULL;
}
void level(node *root)
{
queue<node *>q;
node *a;
if(root)
{
while(!q.empty())
q.pop();
q.push(root);
while(!q.empty())
{
a = q.front();
q.pop();
cout << a->data << ' ';
if(a->lchild)
q.push(a->lchild);
if(a->rchild)
q.push(a->rchild);
}
}
}
node* parent1(node *root, int e)
{
queue<node *>q;
node *a;
node *p = search_node(root, e);
if(root)
{
while(!q.empty())
q.pop();
q.push(root);
while(!q.empty())
{
a = q.front();
q.pop(); ///这里得加一个判断是左孩子还是右孩子的flag 以便在删除中进行判断
if(a->lchild && a->lchild->data == e)
{
flag = 0;
return a;
}
if(a->rchild && a->rchild->data == e)
{
flag = 1;
return a;
}
else
{
if(a->lchild)
q.push(a->lchild);
if(a->rchild)
q.push(a->rchild);
}
}
}
return NULL;
}
void delete_node(node **root, int e)
{
node *p = search_node(*root, e);///找到了要删的节点 接下来进行判断 执行下一步操作
node *q = parent1(*root, e);
if(p == NULL)///1
{
cout << "not founded!" << endl;
return ;
}
///2.要删除的节点没有左右孩子,有父节点。
if(p->lchild == NULL && p->rchild == NULL && q)
{
cout << p->data << endl;
if(flag == 0)///节点 是左孩子
{
q->lchild = NULL;
delete p;
}
else if(flag == 1)
{
q->rchild == NULL;
delete p;
}
}
///3.要删除的node没有左右孩子,没有父节点(即根节点)。
else if(p->lchild == NULL && p->rchild == NULL && !q)
{
(*root) = NULL;
delete p;
}
///4.要删除的node有左孩子没右孩子,有父节点
else if(p->lchild && p->rchild == NULL && q)
{
if(flag == 0)
{
q->lchild = p->lchild;
delete p;
}
else if(flag == 1)
{
q->rchild = p->lchild;
delete p;
}
}
///5.有左右孩子 没父节点
///设定 将node 的右孩子插到它的左孩子里
if(p && p->lchild && p->rchild && !q)
{
///cout << "1" << endl;
node * temp;
temp = p;
while(temp->lchild)
{
temp = temp->lchild;
///cout << "1" << endl;
}
temp->lchild = p->rchild;
///cout << "1" << endl;
delete p;
///cout << "1" << endl;
(*root) = temp;///一直崩 崩到我开始怀疑人生 因为忘改根节点了 改了就好了
}
///6.要删除的node有右孩子没左孩子,有父节点
///这是怎么了 突然胃好疼 不行 我要写完
else if(p->rchild && p->lchild==NULL &&q)
{
if(flag == 0)
{
q->lchild = p->rchild;
delete p;
}
else if(flag == 1)
{
q->rchild = p->rchild;
delete p;
}
}
///7.要被删除的node有右孩子没有左孩子,没有父节点
else if(p->rchild && p->lchild ==NULL && !q)
{
(*root) = p->rchild;
delete p;
}
///8.要被删除的node左右孩子都有,有父节点
else if(p->lchild && p->rchild && q)
{
if(flag == 0)
{
p->lchild->rchild = p->rchild;
q->lchild = p->lchild;
delete p;
}
else if(flag == 1)
{
p->rchild->lchild = p->lchild;
q->rchild = p->rchild;
delete p;
}
}
}
int main()
{
int arr[11]={4,1,45,78,345,23,12,3,6,21};
///为了和中序遍历产生对比 我们打印一下数组
int n = 10;
cout << "the array is : " << endl;
print(arr, n);
cout << endl;
node *parent = NULL;
node *root = NULL;
flag = -1;
///建树
createTree(&root,arr, n); ///采用先建立根节点 然后按序一个一个插得方式建立二叉搜索树
///中序遍历BST 呵呵哒 此时我想到了BTS
cout << "the in_order is:"<< endl;
in(root);
cout << endl;
/*int s;
cin >> s;
node *p = search_node(root, s);///先找个节点 一会删除用
if(p)
{
cout << p->data << endl;
}
else
{
cout << "NULL" << endl;
}
///找某个节点的双亲结点 删除的必备函数 测试一下
p = parent1(root, s);/// parent不能用作函数名 我有点方
if(p)
{
cout << p->data << endl;
cout << flag << endl;
}
else
{
cout << "NULL" << endl;
}
*/
int s;
///接下来就是最难的部分啦
///调用查找函数再找一遍吧
///那么接下来就对所有可能删除的情况进行测试吧
while(cin >> s)
{
delete_node(&root, s);
node *p = parent1(root, s);
if(p && p->lchild)///这里竟然崩了 我很无语 睡一觉起来再说~ 这里修改过了
cout << p->lchild->data << endl;///原来写的是if(p->lchild) 没有判断双亲结点是否空 就崩了
else
cout << "NULL" << endl;/// 这个判断语句写的没什么意义 因为我已经把这个节点删了
///输出肯定为空 但是它却帮我找出了错误 哈哈哈 不然我还得去麻烦大神
cout << "the level_order is:" << endl;
level(root);
cout << endl;
}
///1........1000
///2........6
///3........只有一个根节点的情况
///4&6 .........1
///5...........4
///7..........只有右孩子的根节点
///8..........45
///基本上就这么些情况了 如果缺的话 也就是左右孩子的问题了, 类比一下是很好解决的
return 0;
}
///两天啦 终于解决了 但是写的太慢了 估计以后写的时候还会很慢 唉
/*
the array is :
4 1 45 78 345 23 12 3 6 21
the in_order is:
1 3 4 6 12 21 23 45 78 345
1000
not founded!
NULL
the level_order is:
4 1 45 3 23 78 12 345 6 21
6
6
NULL
the level_order is:
4 1 45 3 23 78 12 345 21
1
NULL
the level_order is:
4 3 45 23 78 12 345 21
45
NULL
the level_order is:
4 3 78 23 345 12 21
4
NULL
the level_order is:
3 78 23 345 12 21
taekwoon oppa salanghei
*/