建立一棵二叉搜索树
二叉搜索树的巨大优势就是:在平均情况下,能够在 O(logN) 的时间内完成搜索和插入元素。
递归版本:
//插入值为key的结点(递归)
TreeNode* insertIntoBST(Tree& t, int key) {
if(t == NULL){ //找到插入目标
t = new TreeNode;
t->val = key;
return t;
}
if(key > t->val) t->right = insertIntoBST(t->right,key); //key大于t->val,去右子树寻找
else if (key < t->val) t->left = insertIntoBST(t->left,key); //key小于t->val,去左子树寻找
else return t; //存在值为key的结点,返回
return t; //返回这棵树
}
迭代版本:
//插入值为key的结点(迭代)
void insertIntoBST2(Tree& t, int key) {
if(t == NULL){
t = new TreeNode;
t->val = key;
return;
}
TreeNode* p = t;
while(p != NULL){
if(key > p->val){ //key大于t->val,去右子树寻找
if(p->right == NULL){
p->right = new TreeNode;
p->right->val = key; //插入成功
return;
}
else p = p->right;
}
else if(key < p->val){ //key小于t->val,去左子树寻找
if(p->left == NULL){
p->left = new TreeNode;
p->left->val = key; //插入成功
return;
}
else p = p->left;
}
else return; //存在值为key的结点,返回
}
}
删除二叉搜索树中值为key的结点
如果该节点是叶子节点,则直接删除它,如果该节点不是叶子节点且有右节点,则用它的后继节点的值替代,然后删除后继节点;如果该节点不是叶子节点且只有左节点,则用它的前驱节点的值替代,然后删除前驱节点。
//中序遍历序列的下一个节点,即比当前节点大的最小节点,简称后继节点。
int successor(TreeNode* p){
p = p->right;
while(p->left != NULL) p = p->left;
return p->val;
}
//中序遍历序列的前一个节点,即比当前节点小的最大节点,简称前驱节点。
int predecessor(TreeNode* p){
p = p->left;
while(p->right != NULL) p = p->right;
return p->val;
}
//删除值为key的结点
TreeNode* deleteNode(Tree& t, int key) {
if(t == NULL) return NULL;
if(key > t->val) t->right = deleteNode(t->right,key); //如果 key > t->val,说明要删除的节点在右子树
else if(key < t->val) t->left = deleteNode(t->left,key); //如果 key < t->val,说明要删除的节点在左子树
else{ //如果 key == root.val,则该节点就是我们要删除的节点
if(t->left == NULL && t->right == NULL) t = NULL; //如果该节点是叶子节点,则直接删除它
else if(t->right != NULL){ //如果该节点不是叶子节点且有右节点,则用它的后继节点的值替代,然后删除后继节点
t->val = successor(t);
t->right = deleteNode(t->right,t->val);
}
else{ //如果该节点不是叶子节点且只有左节点,则用它的前驱节点的值替代,然后删除前驱节点
t->val = predecessor(t);
t->left = deleteNode(t->left,t->val);
}
}
return t;
}
完整代码如下:
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
typedef struct node{
int val;
struct node* left = NULL;
struct node* right = NULL;
}TreeNode,*Tree;
void InOrder(Tree& t){ //二叉树中序遍历
if(t == NULL) return;
InOrder(t->left);
cout<<t->val<<" ";
InOrder(t->right);
}
//插入值为key的结点(递归)
TreeNode* insertIntoBST(Tree& t, int key) {
if(t == NULL){ //找到插入目标
t = new TreeNode;
t->val = key;
return t;
}
if(key > t->val) t->right = insertIntoBST(t->right,key); //key大于t->val,去右子树寻找
else if (key < t->val) t->left = insertIntoBST(t->left,key); //key小于t->val,去左子树寻找
else return t; //存在值为key的结点,返回
return t; //返回这棵树
}
//插入值为key的结点(迭代)
void insertIntoBST2(Tree& t, int key) {
if(t == NULL){
t = new TreeNode;
t->val = key;
return;
}
TreeNode* p = t;
while(p != NULL){
if(key > p->val){ //key大于t->val,去右子树寻找
if(p->right == NULL){
p->right = new TreeNode;
p->right->val = key; //插入成功
return;
}
else p = p->right;
}
else if(key < p->val){ //key小于t->val,去左子树寻找
if(p->left == NULL){
p->left = new TreeNode;
p->left->val = key; //插入成功
return;
}
else p = p->left;
}
else return; //存在值为key的结点,返回
}
}
//中序遍历序列的下一个节点,即比当前节点大的最小节点,简称后继节点。
int successor(TreeNode* p){
p = p->right;
while(p->left != NULL) p = p->left;
return p->val;
}
//中序遍历序列的前一个节点,即比当前节点小的最大节点,简称前驱节点。
int predecessor(TreeNode* p){
p = p->left;
while(p->right != NULL) p = p->right;
return p->val;
}
//删除值为key的结点
TreeNode* deleteNode(Tree& t, int key) {
if(t == NULL) return NULL;
if(key > t->val) t->right = deleteNode(t->right,key); //如果 key > t->val,说明要删除的节点在右子树
else if(key < t->val) t->left = deleteNode(t->left,key); //如果 key < t->val,说明要删除的节点在左子树
else{ //如果 key == root.val,则该节点就是我们要删除的节点
if(t->left == NULL && t->right == NULL) t = NULL; //如果该节点是叶子节点,则直接删除它
else if(t->right != NULL){ //如果该节点不是叶子节点且有右节点,则用它的后继节点的值替代,然后删除后继节点
t->val = successor(t);
t->right = deleteNode(t->right,t->val);
}
else{ //如果该节点不是叶子节点且只有左节点,则用它的前驱节点的值替代,然后删除前驱节点
t->val = predecessor(t);
t->left = deleteNode(t->left,t->val);
}
}
return t;
}
//层次遍历按行输出
void levelOrderTraverse(Tree& t){
if(t == NULL) return;
queue<TreeNode*> q;
TreeNode* p;
q.push(t);
while(!q.empty()){
int width = q.size();
for(int i = 0;i < width;i ++){
p = q.front();
q.pop();
cout<<p->val<<" ";
if(p->left) q.push(p->left);
if(p->right) q.push(p->right);
}
cout<<endl;
}
}
int main(){
Tree t = NULL;
/*
4 3 5 1 6
*/
cout<<"插入4:"<<endl;
insertIntoBST(t,4);
levelOrderTraverse(t);
cout<<"插入3:"<<endl;
insertIntoBST2(t,3);
levelOrderTraverse(t);
cout<<"插入5:"<<endl;
insertIntoBST(t,5);
levelOrderTraverse(t);
cout<<"插入1:"<<endl;
insertIntoBST2(t,1);
levelOrderTraverse(t);
cout<<"插入6:"<<endl;
insertIntoBST(t,6);
levelOrderTraverse(t);
cout<<"中序遍历:"<<endl;
InOrder(t);
cout<<endl<<"删除4:"<<endl;
deleteNode(t,4);
levelOrderTraverse(t);
cout<<"删除5:"<<endl;
deleteNode(t,5);
levelOrderTraverse(t);
}
运行结果: