二叉排序树的简单操作:
(1)查找,——类似于二分查找(较简单,略)
(2)插入,——若新结点已存在,则不插入;否则,插入(较简单,略)
(3)删除,——由于结点的删除会对树造成影响;所以,我们重点谈谈。
分类:
1)删除的结点为叶子结点 —— 直接删除,然后使其 = NULL
2)删除的结点为单孩子结点 —— 让其双亲结点指向它的孩子结点,然后使其 = NULL
2)删除的结点为双孩子结点 ——
方法一:让其左孩子代替它,其右孩子接在其左孩子的最右端
1,,可通过修改结点的值来实现——>前提:递归比较6
2,可通过修改指针来实现——>比较符合初学者
方法二:让其右孩子的最左端代替它,这个最左端的右孩子代替这个最左端。
坑点:1,当删除叶子结点时,应在主树中将其置为空,否则在遍历时会出现异常。
2,当获取某个结点的值时,在不确定的情况下,需判断其是否为空。
下面结合图和代码仔细研读(图有点烂哈)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <functional>
#include <algorithm>
#include <numeric>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <cstring>
#include <conio.h>
using namespace std;
#define NULL 0
struct bstnode
{
int key;
bstnode *lchild, *rchild;
};
bstnode *root = NULL; //根结点
bstnode *parent = NULL; //待插入位置的双亲结点
int bstsearch (int key)
{
struct bstnode *ps;
int mark; //查找标志:0->空树;1->查找成功;2->查找失败,应插入到左子树中;3->查找失败,应插入到右子树中
if(!root)
{
mark = 0;
}
else
{
ps = root;
while(ps)
{
if(ps->key == key)
{
mark = 1;
break;
}
else if(ps->key > key)
{
parent = ps;
ps = ps->lchild;
mark = 2;
}
else
{
parent = ps;
ps = ps->rchild;
mark = 3;
}
}
}
return mark;
}
int bstinsert (int key)
{
bstnode *point;
int mark, flag; //falg:0-》插入 1-》未插入
mark = bstsearch (key);
if(1 == mark)
{
flag = 1;
}
else
{
point = (bstnode *)malloc (sizeof (bstnode));
if(!point)
{
cout << "Memory overflow!";
_getch ();
exit (0);
}
point->key = key;
point->lchild = NULL;
point->rchild = NULL;
if(mark == 0)
{
root = point;
flag = 0;
}
else if(mark == 2)
{
parent->lchild = point;
flag = 0;
}
else
{
parent->rchild = point;
flag = 0;
}
}
return flag;
}
void bst_inorder (bstnode *point)
{
if(point)
{
bst_inorder (point->lchild);
cout << " " << point->key;
bst_inorder (point->rchild);
}
}
//修改值
int bstdelete (bstnode ** del_root, int key)
{
bstnode *ps, *left;
if(*del_root == NULL) //二叉树为空
{
return 0;
}
else
{
if(key < (*del_root)->key) //待删除结点在左子树
{
cout << "left\t";
_getch ();
return bstdelete (&(*del_root)->lchild, key);
}
if(key > (*del_root)->key) //待删除结点在右子树
{
cout << "right\t";
_getch ();
return bstdelete (&(*del_root)->rchild, key);
}
ps = *del_root; //找到待删除结点
if(ps->lchild == NULL && NULL == ps->rchild) //待删除结点为叶子结点
{
*del_root = NULL;
free (ps);
return 1;
}
if(ps->lchild == NULL) //待删除结点只有右子树
{
*del_root = (*del_root)->rchild;
free (ps);
return 1;
}
if(ps->rchild == NULL) //待删除结点只有左子树
{
*del_root = (*del_root)->lchild;
free (ps);
return 1;
}
else
{
if((*del_root)->lchild->rchild == NULL)
{
(*del_root)->key = (*del_root)->lchild->key;
return bstdelete (&ps->lchild, (*del_root)->key);
}
left = ps->lchild;
while(left->rchild != NULL)
{
ps = left;
left = left->rchild;
}
(*del_root)->key = left->key;
return bstdelete (&ps->rchild, (*del_root)->key);
}
}
}
//修改指针1 //还需修改
int bstdelete2 (int key)
{
if(!root)
{
return 0;
}
int flag = bstsearch (key); //判断root中是否存在key
if(1 != flag)
{
return 0;
}
bstnode *ps = root;
if(ps->key == key) //当删除结点为根结点时
{
if(ps->lchild == NULL && ps->rchild == NULL)
{
free (ps);
root = NULL;
ps = NULL;
return 1;
}
if(ps->lchild == NULL)
{
root = ps->rchild;
free (ps);
ps = NULL;
return 1;
}
if(ps->rchild == NULL)
{
root = ps->lchild;
free (ps);
ps = NULL;
return 1;
}
else
{
root = ps->lchild;
bstnode *pCur = ps->lchild;
while(pCur->rchild)
{
pCur = pCur->rchild;
}
pCur->rchild = ps->rchild;
free (ps);
ps = NULL;
return 1;
}
}
else //当删除结点不为根结点时
{
while(key != ps->key) //找到待删除结点
{
parent = ps; //parent为待删除结点的双亲结点
if(key < ps->key)
{
ps = ps->lchild;
}
else
{
ps = ps->rchild;
}
}
if(ps->lchild == NULL && ps->rchild == NULL) //待删除结点为叶子结点
{
if(parent->lchild != NULL && parent->lchild->key == key)
{
parent->lchild = NULL;
}
else
{
parent->rchild = NULL;
}
free (ps);
ps = NULL;
return 1;
}
if(ps->lchild == NULL) //待删除结点只含有右子树
{
if(parent->lchild != NULL && parent->lchild->key == ps->key) //判断待删除结点为双亲结点的哪个孩子
{
parent->lchild = ps->rchild;
}
else
{
parent->rchild = ps->rchild;
}
free (ps);
ps = NULL;
return 1;
}
if(ps->rchild == NULL) //待删除结点只含有左子树
{
if(parent->lchild != NULL && parent->lchild->key == ps->key)
{
parent->lchild = ps->lchild;
}
else
{
parent->rchild = ps->lchild;
}
free (ps);
ps = NULL;
return 1;
}
else //待删除结点既有右子树又有左子树
{
if(parent->lchild != NULL && parent->lchild->key == ps->key)
{
parent->lchild = ps->lchild;
}
else
{
parent->rchild = ps->lchild;
}
bstnode *pCur = ps->lchild;
while(pCur->rchild)
{
pCur = pCur->rchild;
}
pCur->rchild = ps->rchild;
free (ps);
ps = NULL;
return 1;
}
}
}
//修改指针2
int bstdelete3 (int key)
{
if(!root)
{
return 0;
}
int flag = bstsearch (key);
if(1 != flag)
{
return 0;
}
bstnode *ps = root;
if(key == ps->key) //待删除结点为根结点
{
if(ps->lchild == NULL && ps->rchild == NULL)
{
free (ps);
root = NULL;
ps = NULL;
return 1;
}
else if(ps->lchild == NULL)
{
root = ps->rchild;
free (ps);
ps = NULL;
return 1;
}
else if(ps->rchild == NULL)
{
root = ps->lchild;
free (ps);
ps = NULL;
return 1;
}
else
{
bstnode *pCur = ps->rchild;
if(pCur->lchild == NULL) //待删除结点的右子树没有左子树
{
pCur->lchild = ps->lchild;
root = pCur;
free (ps);
return 1;
}
else
{
while(pCur->lchild)
{
parent = pCur; //parnet为欲取代待删除结点的双亲结点
pCur = pCur->lchild;
}
root = pCur;
if(parent->lchild != NULL && parent->lchild->key == pCur->key)
{
parent->lchild = pCur->rchild;
}
else
{
parent->rchild = pCur->rchild;
}
pCur->lchild = ps->lchild;
pCur->rchild = ps->rchild;
free (ps);
ps = NULL;
return 1;
}
}
}
else //待删除结点为非根结点
{
while(key != ps->key)
{
parent = ps; //parent为待删除结点的双亲结点
if(key < ps->key)
{
ps = ps->lchild;
}
else
{
ps = ps->rchild;
}
}
if(ps->lchild == NULL && ps->rchild == NULL)
{
if(parent->lchild != NULL && parent->lchild->key == key)
{
parent->lchild = NULL;
}
else
{
parent->rchild = NULL;
}
free (ps);
ps = NULL;
return 1;
}
else if(ps->lchild == NULL)
{
if(parent->lchild != NULL && parent->lchild->key == key)
{
parent->lchild = ps->rchild;
}
else
{
parent->rchild = ps->rchild;
}
free (ps);
ps = NULL;
return 1;
}
else if(ps->rchild == NULL)
{
if(parent->lchild != NULL && parent->lchild->key == key)
{
parent->lchild = ps->lchild;
}
else
{
parent->rchild = ps->lchild;
}
free (ps);
ps = NULL;
return 1;
}
else
{
bstnode *pCur = ps->rchild; //pCur为欲取代结点
bstnode *pPre = NULL; //pPre为欲取代结点的双亲结点
if(pCur->lchild == NULL)
{
if(parent->lchild != NULL && parent->lchild->key == key)
{
parent->lchild = pCur;
}
else
{
parent->rchild = pCur;
}
pCur->lchild = ps->lchild;
free (ps);
return 1;
}
else
{
while(pCur->lchild)
{
pPre = pCur;
pCur = pCur->lchild;
}
if(parent->lchild != NULL && parent->lchild->key == key)
{
parent->lchild = pCur;
}
else
{
parent->rchild = pCur;
}
if(pPre->lchild != NULL && pPre->lchild->key == pCur->key)
{
pPre->lchild = pCur->rchild;
}
else
{
pPre->rchild = pCur->rchild;
}
pCur->lchild = ps->lchild;
pCur->rchild = ps->rchild;
free (ps);
ps = NULL;
return 1;
}
}
}
}
int main()
{
int kx, falg;
cout << "\n This is bin_sort_tree_insert...";
while(true)
{
cout << "\n\n pelease input the key want to insert('0' to exit):";
cin >> kx;
if(kx == 0)
{
break;
}
falg = bstinsert (kx);
if(1 == falg)
{
cout << "\n\tFound ! And " << kx << "has been int the tree.";
}
else
{
cout << "\n\t Not found ! And " << kx << "has been inserted into the tree.";
}
}
cout << "\n The bin_sort_tree is : \n";
bst_inorder (root);
while(true)
{
cout << "\n\n please input the key want to delete:";
cin >> kx;
falg = bstdelete3 (kx);
if(1 == falg)
{
cout << "\n\n\t" << kx << " has been deleted.......";
}
else
{
cout << "\n\t Failure!";
}
cout << "\n\n The bin_sort_tree is :\n";
bst_inorder (root);
cout << endl;
}
return 0;
}