#include<iostream>
using namespace std;
typedef struct Tree {
int data;
struct Tree* l;
struct Tree* r;
}*BTree;
void insert(BTree root, int data)
{
BTree p, s, tmp=root;
p = root;
while (p)
{
tmp = p;
if (data < p->data)
{
p = p->l;
}
else
{
p = p->r;
}
}
s = (BTree)malloc(sizeof(struct Tree));
s->data = data;
s->l = nullptr;
s->r = nullptr;
if (s->data < tmp->data)
{
tmp->l = s;
}
else
{
tmp->r = s;
}
}
struct Tree* init(int n)
{
BTree root = (BTree)malloc(sizeof(struct Tree));
int data;
cin >> data;
root->data = data;
root->l = nullptr;
root->r = nullptr;
for (int i = 1; i < n; i++)
{
cin >> data;
insert(root, data);
}
return root;
}
int search(BTree root, int key)
{
while (root)
{
if (root->data == key)
{
return 1;
}
else if (root->data > key)
{
root = root->l;
}
else
{
root = root->r;
}
}
return -1;
}
void Delete(BTree root,int key)//删除主要分三种情况
{
BTree p, q;
p = root;
q = p;
while (p)//用p来遍历,q来记录父节点
{
if (p->data == key)
{
break;
}
q = p;
if (p->data > key)
{
p = p->l;
}
else
{
p = p->r;
}
}
if (!p)
{
return;
}
if (!p->l && !p->r)//第一种 删除节点为叶子节点
{
if (q->l == p)
{
q->l = nullptr;
}
else
{
q->r = nullptr;
}
free(p);
}
else if (p->l && !p->r)//第二种 删除的节点只存在左子树
{
if (q->l == p)
{
q->l = p->l;
}
else
{
q->r = p->l;
}
}
else//第三种 删除的节点左右子树都有 选取右子树的最小节点覆盖删除节点
{
q = p;
BTree cur = p;
p = p->r;
while (p->l)
{
cur = p;
p = p->l;
}
if (q->r == p)//如果右子树不存在左节点 极端
{
q->data = p->data;
q->r = p->r;
}
else
{
q->data = cur->l->data;
cur->l = cur->l->r;
//cur->l = nullptr;
}
free(p);
}
}
void Traverse(BTree root)//先序遍历
{
if (root)
{
printf("%d\n", root->data);
Traverse(root->l);
Traverse(root->r);
}
}
void main()
{
//测试删除8 4 18 1 6 11 20 0 3 14 2 13 15 16
BTree root=init(14);
Delete(root, 14);
//cout << search(root, 10);
Traverse(root);
}
二叉搜索树基本操作(增删查改)
最新推荐文章于 2021-03-21 10:16:47 发布