二叉排序树的插入
1、所有比根节点小的往左插,比根节点大的往右插
2、二叉排序树的中序遍历结果是一个升序的序列
3、极值:极大值—最右边
极小值—最左边
递归法
void recursionInsertBST(LPNode* root, int key)
{
LPNode newNode = new Node;
newNode->key = key;
newNode->left = NULL;
newNode->right = NULL;
//如果是空树,则新节点直接作为根节点
if (*root == NULL)
{
*root = newNode;
return;
}
//插入到当前节点的左子树
if ((*root)->left == NULL && (*root)->key > key)
{
(*root)->left = newNode;
return;
}
//插入到当前节点的右子树
if ((*root)->right == NULL && (*root)->key < key)
{
(*root)->right = newNode;
return;
}
//本次循环没有插入节点,删除创建的节点
delete newNode;
//查找左子树
if ((*root)->key > key)
{
recursionInsertBST(&((*root)->left), key);
}
else if ((*root)->key < key)
{
recursionInsertBST(&((*root))->right, key);
}
}
非递归法
void insertBST(LPNode* root, int key)
{
LPNode newNode = new Node;
newNode->key = key;
newNode->left = NULL;
newNode->right = NULL;
if (*root)
{
LPNode head = *root;
LPNode parent = *root;
while (head)
{
parent = head;
if (head->key > key)
head = head->left;
else if(head->key < key)
head = head->right;
}
if (parent->key > key)
{
parent->left = newNode;
return;
}
else if (parent->key < key)
{
parent->right = newNode;
return;
}
}
else
{
//如果是空树,则新节点直接作为根节点
*root = newNode;
return;
}
}
二叉排序树的查找
普通节点
LPNode searchBST(LPNode root, int key)
{
if (root == NULL)
return NULL;
if (root->key > key)
return searchBST(root->left, key);
else if (root->key < key)
return searchBST(root->right, key);
else
return root;
}
极值
/*二分法*/
LPNode searchMinBST(LPNode root)
{
if (root == NULL)
return NULL;
LPNode parent = root;
while (root)
{
parent = root;
root = root->left;
}
return parent;
}
/*二分法*/
LPNode searchMaxBST(LPNode root)
{
if (root == NULL)
return NULL;
LPNode parent = root;
while (root)
{
parent = root;
root = root->right;
}
return parent;
}
二叉排序树的删除
- 1、删除的节点是叶子
- 2、删除的节点只有左子树或者只有右子树
- 2、删除的节点既有左子树又有右子树
bool deleteBST(LPNode* root, int key)
{
if (*root == NULL)
return false;
//找到值为key的节点
if (key == (*root)->key)
{
LPNode q, s;
//待删除的节点是叶子节点
if (((*root)->left == NULL) && ((*root)->right == NULL))
{
q = (*root);
(*root) = NULL;//父节点的子树保存的还是原来的地址,所以会出现异常
delete q;
}
//右子树为空,则只需要重接它的左子树
else if ((*root)->right == NULL)
{
//保存要删除的节点
q = *root;
*root = (*root)->left;
delete q;
}
//左子树为空,只需要重接它的右子树
else if ((*root)->left == NULL)
{
//保存要删除的节点
q = *root;
*root = (*root)->right;
delete q;
}
//左右子树均不为空
else
{
//保存要删除的节点
q = *root;
//保存待删除节点的左孩子地址
s = (*root)->left;
//找到直接前驱
while (s->right)
{
q = s;
s = s->right;
}
//s为待删除节点的直接前驱
(*root)->key = s->key;
//若q下沉,即q不再等于*root
if (q != *root)
{
//重接q的右子树
q->right = s->left;
}
//q没有移动,还是指向root
else
{
//重接q的左子树
q->left = s->left;
}
delete s;
}
return true;
}
else if ((*root)->key > key)
{
int flag = deleteBST(&(*root)->left, key);
return flag;
}
else
{
int flag = deleteBST(&(*root)->right, key);
return flag;
}
}
完整代码
#include<iostream>
#include<stack>
using namespace std;
/*
* 1、所有比根节点小的往左插,比根节点大的往右插
* 2、二叉排序树的中序遍历结果是一个升序的序列
* 3、极值: 极大值---最右边
* 极小值---最左边
*/
typedef struct Node {
int key;
struct Node* left;
struct Node* right;
}Node, * LPNode;
void recursionInsertBST(LPNode* root, int key)
{
LPNode newNode = new Node;
newNode->key = key;
newNode->left = NULL;
newNode->right = NULL;
//如果是空树,则新节点直接作为根节点
if (*root == NULL)
{
*root = newNode;
return;
}
//插入到当前节点的左子树
if ((*root)->left == NULL && (*root)->key > key)
{
(*root)->left = newNode;
return;
}
//插入到当前节点的右子树
if ((*root)->right == NULL && (*root)->key < key)
{
(*root)->right = newNode;
return;
}
//本次循环没有插入节点,删除创建的节点
delete newNode;
//查找左子树
if ((*root)->key > key)
{
recursionInsertBST(&((*root)->left), key);
}
else if ((*root)->key < key)
{
recursionInsertBST(&((*root))->right, key);
}
}
void insertBST(LPNode* root, int key)
{
LPNode newNode = new Node;
newNode->key = key;
newNode->left = NULL;
newNode->right = NULL;
if (*root)
{
LPNode head = *root;
LPNode parent = *root;
while (head)
{
parent = head;
if (head->key > key)
head = head->left;
else if(head->key < key)
head = head->right;
}
if (parent->key > key)
{
parent->left = newNode;
return;
}
else if (parent->key < key)
{
parent->right = newNode;
return;
}
}
else
{
//如果是空树,则新节点直接作为根节点
*root = newNode;
return;
}
}
void midOrder(LPNode root)
{
if (root != NULL)
{
midOrder(root->left);//左
cout << root->key << " ";//根
midOrder(root->right);//右
}
}
LPNode searchBST(LPNode root, int key)
{
if (root == NULL)
return NULL;
if (root->key > key)
return searchBST(root->left, key);
else if (root->key < key)
return searchBST(root->right, key);
else
return root;
}
/*二分法*/
LPNode searchMinBST(LPNode root)
{
if (root == NULL)
return NULL;
LPNode parent = root;
while (root)
{
parent = root;
root = root->left;
}
return parent;
}
/*二分法*/
LPNode searchMaxBST(LPNode root)
{
if (root == NULL)
return NULL;
LPNode parent = root;
while (root)
{
parent = root;
root = root->right;
}
return parent;
}
/*
* 1、删除的节点是叶子
* 2、删除的节点只有左子树或者只有右子树
* 2、删除的节点既有左子树又有右子树
*/
bool deleteBST(LPNode* root, int key)
{
if (*root == NULL)
return false;
//找到值为key的节点
if (key == (*root)->key)
{
LPNode q, s;
//待删除的节点是叶子节点
if (((*root)->left == NULL) && ((*root)->right == NULL))
{
q = (*root);
(*root) = NULL;//父节点的子树保存的还是原来的地址,所以会出现异常
delete q;
}
//右子树为空,则只需要重接它的左子树
else if ((*root)->right == NULL)
{
//保存要删除的节点
q = *root;
*root = (*root)->left;
delete q;
}
//左子树为空,只需要重接它的右子树
else if ((*root)->left == NULL)
{
//保存要删除的节点
q = *root;
*root = (*root)->right;
delete q;
}
//左右子树均不为空
else
{
//保存要删除的节点
q = *root;
//保存待删除节点的左孩子地址
s = (*root)->left;
//找到直接前驱
while (s->right)
{
q = s;
s = s->right;
}
//s为待删除节点的直接前驱
(*root)->key = s->key;
//若q下沉,即q不再等于*root
if (q != *root)
{
//重接q的右子树
q->right = s->left;
}
//q没有移动,还是指向root
else
{
//重接q的左子树
q->left = s->left;
}
delete s;
}
return true;
}
else if ((*root)->key > key)
{
int flag = deleteBST(&(*root)->left, key);
return flag;
}
else
{
int flag = deleteBST(&(*root)->right, key);
return flag;
}
int main()
{
LPNode root = NULL;
int keyArray[11] = { 15,6,18,3,7,17,20,2,4,13,9 };
for (int i = 0; i < sizeof(keyArray) / sizeof(int); i++)
{
//二叉排序树的插入
//recursionInsertBST(&root, keyArray[i]);
insertBST(&root, keyArray[i]);
}
//遍历二叉树
midOrder(root);
//查找二叉排序树的某个节点
LPNode find = searchBST(root, 20);
if (find == NULL)
cout << endl << "未找到!" << endl;
else
cout << endl << "找到了:" << find->key << "!" << endl;
//二叉排序树的极值
LPNode MIN = searchMinBST(root);
cout << "min: " << MIN->key << endl;
LPNode MAX = searchMaxBST(root);
cout << "max: " << MAX->key << endl;
//删除节点15
bool flag = deleteBST(&root, 18);
if (flag)
{
cout << "已删除" << endl;
midOrder(root);
}
return 0;
}