zoukankan      html  css  js  c++  java
  • 二叉搜索树

    // 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;
    }
  • 相关阅读:
    写给所有的IT民工们
    如何不重启系统加载.SYS文件
    六十八个经典故事
    利用C#重启远程计算机
    无为无不为
    男人心里到底藏着哪些秘密?
    Microsoft好员工的十个标准
    javascript版的日期输入控件
    书写NDIS过滤钩子驱动实现ip包过滤
    男人25岁前的忠告#必阅
  • 原文地址:https://www.cnblogs.com/candycloud/p/3341512.html
Copyright © 2011-2022 走看看