// Binary_search_tree.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
using namespace std;
struct node{
int key;
node *p;
node *left;
node *right;
};//二叉树节点
//创造一颗树,这棵树只有一个节点,关键值为value,其他指针值为空(NULL)
node *Tree_create(int value){
node *root = new node;
root->left = NULL;
root->right = NULL;
root->key = value;
return root;
}
//插入一个节点函数,插入的节点关键值给定,大概步骤:1.与当前节点关键值比较2如果大于当前节点关键值
向右移动一个节点,如果小于当前节点关键值,向左移动一个节点 3.重复以上步骤,直到再次将移动到得节点为空,将要插入的值放在该空节点处
void Tree_insert(int value, node *root){
node *z = new node;
node *y = new node;
node *x = new node;
z->key = value;
z->left = NULL;
z->right = NULL;
z->p = NULL;
if(root == NULL){
root = z;
}else{
if(root->key <= value){
y = root->right;
}else{
y = root->right;
}
x = root;
while(y != NULL){
x = y;
if(y->key <= value){
y = y->right;
}else{
y = y->left;
}
}
z->p = x;
if(x->key <= value){
x->right = z;
}else{
x->left = z;
}
}
}
//插入一个数组,构造一个大的二叉搜索树
void Tree_insert_array(int length,int *A,node *root){
for(int i = 0;i < length;i++)
Tree_insert(A[i],root);
}
//求最大值,原理:根节点开始一直向右至最右节点,返回该最有节点。
node *Tree_maximum(node *root){
node *x;
node *y;
if(root == NULL){
return NULL;
}else{
x = root;
y = x->right;
while(y != NULL){
x = y;
y = y->right;
}
return x;
}
}
//求最小值,从根节点开始,一直向左,到最左,返回该最左节点
node *Tree_minimum(node *root){
node *x;
node *y;
if(root == NULL){
return NULL;
}else{
x = root;
y = x->left;
while(y != NULL){
x = y;
y = y->left;
}
return x;
}
}
//求给定节点后继(关键值大于该节点关键值的节点中关键值最小的那个)
node *Tree_successor(node *root,node *x){
if(x->right != NULL)return Tree_minimum(x->right);
node *y = x->p;
node *z = x;
while(y != NULL&&z == y->right){
z = y;
y = y->p;
}
return y;
}
//求前驱(关键值小于当前节点关键值节点中关键值最小的那个节点)
node *Tree_prodesessor(node *root,node *x){
if(x->left != NULL)return Tree_maximum(x->left);
node *y = x->p;
node *z = x;
while(y != NULL&&z == y->left){
z = y;
y = y->p;
}
return y;
}
//查找给定关键值的节点
node *Tree_search(node *root,int value){
node *x;
if(root == NULL){
cout<<"返回空1"<<endl;
return NULL;
}else{
x = root;
while(x != NULL&&x->key != value){
if(x->key < value){
x = x->right;
}else{
x = x->left;
}
}
if(x == NULL)cout<<"返回空2"<<endl;
return x;
}
}
//用一个子树替换另一个子树
void Tree_transplant(node *u,node *v){
if(u->p == NULL){u = v;}
else if(u = u->p->left){
u->p->left = v;
}else{
u->p->right = v;
}
if(v != NULL){
v->p = u->p;
}
}
//从一个树中删除指定节点,描述:从一颗二叉搜索树中删除一个节点z的整个策略分为三种基本情况,但是有一种情况有点棘手:
1.如果z没有孩子节点,那么只有简单的把它删除,并修改他的父节点,用NULL作为孩子来替换z
2.如果z只有一个孩子,那么将这个孩子提升到树中z的位置上,并修改z的父节点,用z的孩子来替换z
3.如果z有两个孩子,那么找z的后继y(一定在z的右子树中),并让y占据树中z的位置。z的原来右子树部分成为y的新的右子树,并且z的做左子树成为y的新的左子树。这种情况稍显麻烦,因为海域y是否为z的有孩子相关
void Tree_delete(node *root,node *z){
if(z->left == NULL){
Tree_transplant(z,z->right);
}else if(z->right == NULL){
Tree_transplant(z,z->left);
}else{
node *y = Tree_minimum(z->right);
if(y->p != z){
Tree_transplant(y,y->right);
y->right = z->right;
y->right->p = y;
}
Tree_transplant(z,y);
y->left = z->left;
y->left->p = y;
}
}
void Tree_middle(node *root){//中序遍历二叉树,如果二叉树是搜索树,则输出为排序结果
if(root->left != NULL)Tree_middle(root->left);
cout<<root->key<<endl;
if(root->right != NULL)Tree_middle(root->right);
}
int main(){
node *root = Tree_create(0);
int s[] = {4,9,65,5,8,6,32,23,65,65};
Tree_insert_array(10,s,root);
cout<<Tree_search(root,8)->key<<endl;
cout<<Tree_maximum(root)->key<<endl;
cout<<Tree_minimum(root)->key<<endl;
cout<<Tree_successor(root,Tree_search(root,65))->key<<endl;
cout<<Tree_prodesessor(root,Tree_search(root,6))->key<<endl;
Tree_middle(root);
Tree_delete(root,Tree_search(root,6));
Tree_search(root,6);
system("pause");
return 0;
}