zoukankan      html  css  js  c++  java
  • 二叉排序树的基本操作

     //节点
    typedef struct bsnode{
       int data;
       struct bstree *lchild;
       struct bstree *rchild;
    }bsnode,*bstree;
     
    ------------------------------------------------------------------------------------
     
     创建二叉排序树:
     
    1创建二叉树:
    void createbstree(bstree &bt){ //调用插入函数逐个插入节点
        int key;
        scanf("%d",&key);
       if(key!=' '){
           insertnode(bt,key);
           scanf("%d",&key);
       }
    }
     
    2.插入节点:
     
    bstree insertbsnode(bstree bt,char key){
        bstree p=bt;
        while(p){                //找到要插入的位置,当结束时p为空,pre为要插入节点的双亲
            pre=p;
            if(p->data==key)return bt;
            else if(keydata) p=p->lchild;
            else p=p->rchild;
        }
     
        q=(bstree)maliic(sizeof(bsnode));
        q->data=key;
        q->lchild=0;
        q->rchild=0;
     
        if(!bt)  bt=q;
        else{
            if(keydata)
                pre->lchild=q;
            else
                pre->rchild=q;
        }
        return bt;
    }
     
    3.删除树(调用删除函数逐个删除节点)
     
    void deleteTree(BiTree T){
        if(!T)
            return OK;
        else{
            if(T->lchild)
                deleteTree(T->firstchild);
            if(T->lchild)
                deleteTree(T->nextsibling);
            free(T);
            T=NULL;
        }
    }
     
    4.删除节点:
     
    bstree deletebsnode(bstree bt){
        bstree p=bt;
        while(p){
        pre=p;                     //标记其父节点以便删除
        if(key==p->data) break;      //找到要删除的节点
        else if(keydata)
            p=p->lchild;
        else
            p=p->rchild;
       }
        if(!bt||!p)  return bt;             // 树为空或者没有找到
        if(p->lchild==NULL||p->rchild==NULL)  //非空但要删除的节点没有左/右子树/没有孩子
            if(pre==NULL){              //要删除的节点为根节点
              if(!p->child)
                bt=p->rchild;
              else
                bt=p->lchild;
            }
           else{                       //要删除的节点不为根节点
             if(!p->lchild){
                if(p==pre->lchild)
                   pre->lchild=p->rchild;
                else
                   pre->rchild=p->rchild;
             }
             else{
                if(p==pre->lchild)
                    pre->lchild=p->lchild;
                else
                    pre->rchild=p->lchild;
            }
           }
        else{  //要删除的节点左右字数都存在。此时找出左子树的最大值,及左子树的最右孩子/根节点,将其复制到要删除的节点上,然后删除该孩子
            pre=p;       //保留p指针指向要删除的节点,用俩个指针分别指向前驱及后继
            q=pre->lchild;
            while(q->rchild){    //找出左子树的最右孩子
               pre=q;
               q=pre->rchild;
            }
            p->data=q->data;   //将左子树最右孩子或者左子数根节点的值赋予要删除的节点
            if(pre==p)           //左子树没有最右孩子
                pre->lchild=q->lchild;
            else                 //找到了最右孩子,此时最右孩子一定为其前驱的右孩子
                pre->rchild=q->lchild;
        }
    }
     
    -----------------------------------------------------------------------------------
    二叉排序树的遍历(与二叉树遍历算法一样)
     
    1.递归遍历
     
    //先序遍历
    void PreOrderTraverse(BsTree &T){
       if(T){
          visit(T->data);
          PreOrderTraverse(T->lchild);
          PreOrderTraverse(T->rchild);
       }
      return OK;
    }
     
    //中序遍历
    void InOrderTraverse(BsTree &T){
      if(T){
        InOrderTraverse(T->lchild);
        visit(T->data);
        InOrderTraverse(T->lchild);
      }
      return OK;
    }
     
    //后序遍历
    void PostOrderTraverse(BsTree &T){
      if(T){
        PostOrderTraverse(T->lchild);
        PostOrderTraverse(T->rchild);
        visit(T->data);
      }
    }
     
     
    2.非递归遍历,用栈辅助。
     
    算法思想:把根节点及所有做孩子依次压入栈,再依次取出把其右孩子压入栈,再依次探查其左右孩子
     
    //先序遍历
    void PreOrderTraver(BsTree &T){
        Stack S;
        IniyStack(S);
        BsTree p=T;
        while(p||!emptyStack(S)){
           if(p){
            visit(p->data);
            Push(S,p);
            p=p->lchild;
           }
           else{
            Pop(S,p);
            p=p->rchild;
           }
        }
        return OK;
    }
     
    //中序遍历
    void InOrderTraverse(Bstree &T){
      Stcak S;
      InitStack(S);
      BsTree p=T;
      while(p||!emptyStqck(S)){
        if(p){
            Push(S,p);
            p=p->lchild;
        }
        else{
            Pop(S,p);
            visit(p->data);
            p=p->rchild;
        }
      }
      return OK;
    }
     
    //后序遍历
    void PostOrderTraver(BsTree &T){
       Stack S;
       InitStack(S);
       BsTree p=T;
       while(p||!emptyStack(S)){
          if(p){
            push(S,p);
            p=p->lchild;
          }
          else{
            if(p->rchild==NULL||pre==p->rchild){
                visit(T->data);
                pre=p;
                p=NULL;
            }
            else{
                p=p->rchild;
            }
          }
       }
       return OK;
    }
     
    //层次遍历二叉树,借助队列
    void LevelOrderTreaverse(BsTree &T){
       Queue Q;
       InitQueue(Q);
       BsTree p=T;
       Enqueu(Q,p);
       while(!emptyQueue(Q)){
          DeQueue(Q,p);
          if(p){
            visit(p->data);
            EnQueue(Q,p->lchild);
            EnQUeue(Q,p->rchild);
          }
       }
       return OK;
    }
     
     
     
    ---------------------------------------------------------------------------------
     
    查找某个节点x
     
    查找某个信息是否在二叉树中(先序递归遍历)
    void searchch(BsTree T,char ch){
       BsTree p=T;
       if(p){
        if(p->data==ch)
            return p;
        else{
            searchch(T->lchild,ch);
            searchch(T->rchild,ch);
        }
       }
    }
     
    ---------------------------------------------------------------------------------
     
    插入节点,删除节点,交换左右子树
     
    1.插入节点
     
    在遍历的基础上找到其父节点再插入。
     
    2.删除节点
     
    在遍历的基础上找该节点再删除。
     
    3.交换左右子树
     
    //递归法
    void exchange(BsTree T){
       BsTree item;
       if(T){
         exchange(T->lchild);
         exchange(T->rchild);
     
         item=T->lchild;
         T->lchild=T->rchild;
         T->rchild=item;
       }
    }
    //非递归法
    利用非递归遍历交换
     
     
    ------------------------------------------------------------------------------------
    求节点个数/叶子节点个数,树的深度
     
    1.树的结点个数
     
    //递归求解
    void NodeNum(BsTree T)
    {
        if(!T)
            return 0;
        else
            return NodeNum(T->lchild)+NodeNum(T->rchild)+1;
    }
     
    //非递归求解
     
    利用非递归遍历方法求解
     
    ---------------------------------
     
    2.求叶子节点个数:
     
    //递归求解
    void leavenum(BsTree T){
       if(T){
          if(T->lchild==NULL&&T->rchild==NULL)
            return 1;
          else
            return leavenum(T-lchild)+leavenum(T->rchild);
       }
    }
     
    //非递归求解
    利用非递归遍历求解
     
     
    -----------------------------------
     
    3.求二叉树的深度
     
    void depth(BsTree T){
       BsTree P=T;
       int lh=0,rh=0;
       if(!p)
          return 0;
       else{
          lh=depth(T->lchild);
          rh=depth(T->rchild);
          return (lh>rh?lh:rh)+1;
       }
    }
     
    ---------------------------------------------------------------------------------------------
  • 相关阅读:
    usb3.0 bMaxBurst最大支持多少个 这个描述符什么时候被读取
    盒式图|加置信椭圆的散点图|分组盒式图|分组散点图|马赛克图|
    协方差分析|随机区组设计|样本单位|样本容量|变异系数|片面误差|抽样误差|真实性|精密度|重复性|精确程度|计数数据|区间变量|离散型变量|数值变量
    试验指标|试验单位|均方|随机模型|固定模型|字母标记法|LSR|q检验|LSD|重复值|弥补缺失数据|可加性|平方根转换|对数转换|反正弦转化
    2×c列联表|多组比例简式|卡方检验|χ2检验与连续型资料假设检验
    显著水平|区间估计|假设检验|显著性|第一类错误|Ⅱ类错误|β错误|t检验|连续性矫正|二项分布的假设检验|样本百分率|
    估计量|估计值|矩估计|最大似然估计|无偏性|无偏化|有效性|置信区间|枢轴量|似然函数|伯努利大数定理|t分布|单侧置信区间|抽样函数|
    单因素方差分析
    左偏|有偏|中心极限定理|卡方分布|
    正交试验
  • 原文地址:https://www.cnblogs.com/yujon/p/5467599.html
Copyright © 2011-2022 走看看