/**
* 二叉查找树
* 和二分查找一样,插入和查找的时间复杂度均为O(logn),但是在最坏的情况下仍然会有O(n)的时间复杂度
*/
#include "tree.h"
#include <iostream>
using namespace std;
typedef struct BiTNode{
int data;
BiTNode*lchild;
BiTNode*rchild;
}BiTNode;
//递归插入
BiTNode *RecursiveInsertBSTree(BiTNode *root, int val) {
BiTNode *p = (BiTNode *) malloc(sizeof(BiTNode));
p->data = val;
p->lchild = NULL;
p->rchild = NULL;
if (root == NULL) {
root = p;
return root;
}
if (val < root->data) {
root->lchild = RecursiveInsertBSTree(root->lchild, val);
} else {
root->rchild = RecursiveInsertBSTree(root->rchild, val);
}
return root;
}
/** 非递归插入
* 先挨个比较找到要插入的位置
* 确定是根还是左孩子还是右孩子
*/
BiTNode *InsertBSTree(BiTNode *root, int val) {
BiTNode *p = (BiTNode *) malloc(sizeof(BiTNode));
p->data = val;
p->lchild = NULL;
p->rchild = NULL;
BiTNode *q = root;
BiTNode *parent = NULL;
while (q != NULL) {
parent = q;
if (val > q->data) {
q = q->rchild;
} else {
q = q->lchild;
}
}
if (root == NULL) {
root = p;
} else if (val < parent->data) {
parent->lchild = p;
} else {
parent->rchild = p;
}
return root;
}
//非递归查找 小于遍历左子树否则遍历右子树
BiTNode *SearchBSTree(BiTNode *root, int val) {
if (root == NULL) {
return NULL;
}
BiTNode *p = root;
while (p != NULL) {
if (p->data == val) {
return p;
}
if (val < p->data) {
p = p->lchild;
} else {
p = p->rchild;
}
}
return NULL;
}
//递归查找
BiTNode *RecursiveSearchBSTree(BiTNode *root, int val) {
if (root == NULL) {
return NULL;
}
if (root->data == val) {
return root;
}
if (val < root->data) {
return RecursiveSearchBSTree(root->lchild, val);
} else {
return RecursiveSearchBSTree(root->rchild, val);
}
}
//删除
/**删除的节点分为三类:
* 度为0的节点: 区分根和叶子节点直接删除
* 度为1的节点
* 度为2的节点
* 先遍历比较找到要删除的节点并记录该节点的父节点
*/
bool DeleteBSTree(BiTNode *root, int val) {
if (root == NULL) {
return false;
}
BiTNode *p = root;
BiTNode *parent = NULL;
bool find = false;
while (p != NULL && !find) {
if (p->data == val) {
find = true;
} else if (val < p->data) {
parent = p;
p = p->lchild;
} else {
parent = p;
p = p->rchild;
}
}
if (p == NULL) {
return false;
}
if (p->lchild == NULL && p->rchild == NULL) {//度为0的节点直接删除
if (p == root) {
root = NULL;
} else if (parent->lchild == p) {
parent->lchild = NULL;
} else {
parent->rchild = NULL;
}
free(p);
return true;
}
if (p->lchild == NULL || p->rchild == NULL) {//度为1的节点
if (p == root) {
if (p->lchild != NULL) {
root = p->lchild;
} else {
root = p->rchild;
}
} else if (p->lchild != NULL) {
if (parent->lchild == p) {
parent->lchild = p->lchild;
} else {
parent->rchild = p->lchild;
}
} else {
if (parent->lchild == p) {
parent->lchild = p->rchild;
} else {
parent->rchild = p->rchild;
}
}
free(p);
return true;
}
BiTNode *s = p->lchild;//度为2的节点
BiTNode *sp = p;
while (s->rchild != NULL) { //找到右子树中的最大值(右子树的最右边的值)作为删除节点的值
sp = s;
s = s->rchild;
}
p->data = s->data;
if (sp == p) { //如果待删除节点没有右子树,直接把左孩子指向左子树
sp->lchild = s->lchild;
} else { //找到了右子树最大值A之后 需要把A的左孩子赋值给A的父的右孩子
sp->rchild = s->lchild;
}
free(s);
return true;
}