• 二叉排序树的基本操作


     //节点
    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;
       }
    }
     
    ---------------------------------------------------------------------------------------------
  • 相关阅读:
    IP路由选择过程
    Netstat命令详解
    路由器的硬件结构
    路由器发展编年史 完结篇
    制作自己博客园文章签名
    路由器发展编年史 发展篇
    距离矢量路由协议_(4)
    路由器的基本功能
    分组交换、报文交换、电路交换
    动态路由中的几种常见metric
  • 原文地址:https://www.cnblogs.com/yujon/p/5467599.html
Copyright © 2020-2023  润新知