zoukankan      html  css  js  c++  java
  • 二叉排序树(Binary Sort Tree)

    参考文章:http://blog.csdn.net/ns_code/article/details/19823463

    不过博主的使用第一种方法操作后的树已经不是二叉排序树了,值得深思!!

    #include "stdio.h"
    #include "stdlib.h"
    
    //二叉链表结点 
    typedef struct Node{
        int data;
        struct Node *lchild,*rchild;
    }Node,*BSTree;
    
    
    /*
    在指针pTree所指的二叉排序树中递归查找关键字为key的元素,
    若查找成功,则返回ture,并将 查找到的数据对应的节点指针 保存在p中,
    否则返回0,并将 查找路径上访问的最后一个节点指针 保存在p中。
    这里的参数f指向每次递归遍历的子树的根节点的父节点,即始终是参数pTree的父节点, 
    它的初始值为NULL,其目的是跟踪查找路径上访问的当前节点的父节点(即上一个访问节点)
    该函数用来被后面的插入结点函数调用。
    */
    int search_Node(BSTree pTree,int key,BSTree f,BSTree &p)
    {
        if(!pTree){
            p = f;
            return 0;
        }else if(key == pTree->data){
            p = pTree;
            return 1;
        }else if(key > pTree->data){
            search_Node(pTree->rchild,key,pTree,p);
        }else{
            search_Node(pTree->lchild,key,pTree,p);
        }
        
    }
    
    
    /*
    往二叉排序树种插入结点 
    当在pTree所指向的二叉排序树中查找不到关键字为key的数据元素时,
    将其插入该二叉排序树,并返回1,否则返回0。
    树空时插入会改变根节点的值,因此要传入引用。
    
     */
    int insertNode(BSTree &pTree,int key)
    {
        BSTree p;
        if(!search_Node(pTree,key,NULL,p)){
            
            BSTree pNew = (BSTree)malloc(sizeof(Node));  //产生新元素的结点 
            pNew->lchild = pNew->rchild = NULL;
            pNew->data = key;
            
            if(!p){
                pTree = pNew;            //如何树空,直接将pNew置为根节点 
            }else{
                if(key > p->data){
                    p->rchild = pNew;        //作为右孩子插入p的右边 
                }else{
                    p->lchild = pNew;        //作为左孩子插入p的左边 
                }        
            }
            return 1;
        }else
            return 0;
        
    }
    
    
    //创建二叉排序树 
    BSTree create_BSTree(int *arr,int num)
    {
        BSTree pTree = NULL;
        int i;
        for(i=0;i<num;i++)
            insertNode(pTree,arr[i]);
        return pTree;
        
    }
    
    //递归中序遍历二叉树,得到元素从小到大的有序排列 
    void InorderTraverse(BSTree pTree)
    {
        if(pTree){        
            InorderTraverse(pTree->lchild);
            printf("%d ",pTree->data);
            InorderTraverse(pTree->rchild);    
        }
    }
    
    //修改左子树的方法删除结点 
    int delete_Node1(BSTree &p)
    {
        BSTree q,s;
        if(!p->lchild){                  //左子树为空,只需重新接上右子树    
            q = p;
            p = p->rchild;
            free(q);
        }else if(!p->rchild){        //右子树为空,只需重新接上左子树
            q = p;
            p = p->lchild;
            free(q);
        }else{                        //如果左右子树都不为空
                                    //我们这里采取修改左子树的方法,也可以修改右子树,方法类似
            q = p;
            s = p->lchild;            //取待删节点的左节点
            while(s->rchild){        //一直向右,最终s为待删节点的前驱节点。
                                    //如果将各节点元素按从小到大顺序排列成一个序列,
                                    //则某节点的前驱节点即为序列中该节点的前面一个节点
                q = s;
                s = s->rchild;
            }
            //用s来替换待删节点p
            p->data = s->data;
            //根据情况,将s的左子树重接到q上
            if(p != q){
                q->rchild = s->lchild;
            }else{
                q->lchild = s->lchild;
            }    
            free(s); 
        }
        return 1;
    }
    
    //修改右子树的方法删除结点
    int delete_Node2(BSTree &p)
    {
        BSTree q,s;
        if(!p->lchild){                //左子树为空,只需重新接上右子树
            q = p;
            p = p->rchild;
            free(q);
        }else if(!p->rchild){        //右子树为空,只需重新接上左子树
            q = p;
            p = p->lchild;
            free(q);
        }else{
            q = p;
            s = p->rchild;
            while(s->lchild){
                q = s;
                s = s->lchild; 
            }
            //用s来替换待删节点p
            p->data = s->data;
            //根据情况,将s的左子树重接到q上
            if(p != q){
                q->lchild = s->rchild;
            }else{
                q->rchild = s->rchild;
            }
            free(s);
        }
        return 1;
    } 
    
    //删除结点 
    int delete_BSTree(BSTree &pTree,int key)
    {
        if(!pTree){            //不存在关键字为key的结点 
            return 0;
        }else{
            if(key == pTree->data){
            //    return delete_Node1(pTree);
                return delete_Node2(pTree);
            }else if(key > pTree->data){
                return delete_BSTree(pTree->rchild,key);
            }else{
                return delete_BSTree(pTree->lchild,key);
            }
        }
    }
    
    
    int main()
    {
        BSTree pTree;
        int i,num,flag;
        printf("请输入节点的个数:");
        scanf("%d",&num);
    //    printf("%d
    ",num);
        
        int *arr = (int *)malloc( num * sizeof(int));
        for(i=0;i<num;i++)
            scanf("%d",arr+i);
        
        pTree = create_BSTree(arr,num);
        printf("中序遍历该二叉排序树的结果:");  
        InorderTraverse(pTree);printf("
    "); 
        
        printf("请输入要删除的结点:");
        scanf("%d",&num);
        flag = delete_BSTree(pTree,num);
        if(flag){
            printf("删除成功!
    ");
        }else{
            printf("删除失败!
    ");
        }
        printf("中序遍历该二叉排序树的结果:");
        InorderTraverse(pTree);printf("
    "); 
    
    
        return 0;
    }
    View Code

    敲敲代码有益身心,嘎嘎

    参考书籍:《大话数据结构》

  • 相关阅读:
    C#
    C#
    ssh学习笔记
    (已解决)Could not open '/var/lib/nova/mnt/*/volume-*': Permission denied
    RPCVersionCapError: Requested message version, 4.17 is incompatible. It needs to be equal in major version and less than or equal in minor version as the specified version cap 4.11.
    如何在linux下安装idea
    The system has no LUN copy license
    调整mysql数据库最大连接数
    mysql数据库编码问题
    cinder支持nfs快照
  • 原文地址:https://www.cnblogs.com/heyijing/p/4826472.html
Copyright © 2011-2022 走看看