本文代码包括二叉排序树的创建,查找,结点删除,结点插入。以及结点删除代码分析。
代码见下文。
删除结点情况结合代码分析
删除结点值等于key的结点
line 34: 指针 parent 指向 key的父结点 或者 NULL
line 42: 指针 p 指向 key 或者 NULL
line 45:
- key的左右子树都非空
- key的一个子树为空
- key的左右子树都为空
第一种情况:
找key的左子树的最大值,实质是左子树的最右下值,替换掉key,再处理找到的左子树最大值
指针q指向 key的左子树中的最大值
指针q_parent指向 q的父结点
line 54: 找到顶替key结点的值,即q,使得p.data=q.data,然后处理q
line 55: 根据q所在位置的不同分别处理,是 q_parent 的左子树还是右子树来接受q的左子树,见下图
第二种情况:
语句ABCD可在具体代码中查看,见下文代码
// 使用q保存非空的子树
if
line 63:语句A
else
line 65:语句B
// 使用parent原来保存p结点的指针保存q结点
if
line 70:语句C
else
line 72:语句D
AC,AD,BD,BC四种情况如下图
上述描述的第二种情况都是p为非根节点的情况
line:67
当p为根时,parent==NULL
line:68
T指向根节点,此时还属于第二种情况,所以让T指向p下的非空结点就可以了,如下图
第三种情况:
运行line70或者line72,parent的一个子树=NULL,所以p结点就被删掉了。
注:line 31:q=NULL
代码
typedef struct Node
{
int data;
struct Node *left, *right;
} * BSTree;
BSTree CreateBST(int A[], int n)
{
BSTree bst = NULL;
for (int i = 0; i < n; i++)
InsertData(bst, A[i]);
return bst;
}
void InsertData(BSTree &T, int val)
{
if (T == NULL)
{
T = (BSTree)malloc(sizeof(struct Node));
T->data = val;
T->left = T->right = NULL;
}
else
{
if (T->data < val)
InsertData(T->right, val);
else
InsertData(T->left, val);
}
}
void DelData(BSTree &T, int key)
{
if (!T)
return;
BSTree p = T, parent = NULL, q = NULL;
while (p->data != key)
{
parent = p;
if (key < p->data)
p = p->left;
else
p = p->right;
}
// not find key
if (!p)
return;
if (p->left != NULL && p->right != NULL)
{
q = p->left;
BSTree q_parent = p;
while (q->right != NULL)
{
q_parent = q;
q = q->right;
}
p->data = q->data;
if (q_parent == p)
q_parent->left = q->left;
else
q_parent->right = q->left;
free(q);
return;
}
else if (p->right != NULL)
q = p->right;
else if (p->left != NULL)
q = p->left;
if (parent == NULL)
T = q;
else if (parent->right == p)
parent->right = q;
else if (parent->left == p)
parent->left = q;
free(p);
}
BSTree FindKey(BSTree T, int key)
{
if (T)
{
if (T->data == key)
return T;
else if (T->data > key)
return FindKey(T->left, key);
else
return FindKey(T->right, key);
}
return NULL;
}
void Display(BSTree bst)
{
queue<BSTree> qu;
if (bst != NULL)
{
qu.push(bst);
}
while (!qu.empty())
{
BSTree bst = qu.front();
qu.pop();
cout << bst->data << " ";
if (bst->left)
qu.push(bst->left);
if (bst->right)
qu.push(bst->right);
}
}