• 排序二叉树节点的删除


    全部代码

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <assert.h>
      4 
      5 typedef struct node
      6 {
      7     int nValue;
      8     struct node *pLeft;
      9     struct node *pRight;
     10 }BiTree;
     11 
     12 void Add(BiTree **ppRoot, int nNum)
     13 {
     14     BiTree *pTemp = NULL;
     15     BiTree *pNode = NULL;
     16 
     17     assert(ppRoot!=NULL);
     18 
     19     //临时节点开辟空间
     20     pTemp = (BiTree *)malloc(sizeof(BiTree));
     21     if(NULL == pTemp)
     22     {
     23         printf("pTemp空间分配失败!
    ");
     24         exit(-1);
     25     }
     26     pTemp->nValue = nNum;
     27     pTemp->pLeft = NULL;
     28     pTemp->pRight = NULL;
     29 
     30     //空树
     31     if(NULL == *ppRoot)
     32     {
     33         *ppRoot = pTemp;
     34         return;
     35     }
     36 
     37     pNode = *ppRoot;
     38 
     39     //非空树
     40     while(pNode != NULL)
     41     {
     42         //比根大
     43         if(nNum > pNode->nValue)
     44         {
     45             //向右走
     46             if(NULL == pNode->pRight)
     47             {
     48                 pNode->pRight = pTemp;
     49                 return;
     50             }
     51             else
     52             {
     53                 pNode = pNode->pRight;
     54             }
     55         }
     56         //比根小
     57         else if(nNum < pNode->nValue)
     58         {
     59             //向左走
     60             if(NULL == pNode->pLeft)
     61             {
     62                 pNode->pLeft = pTemp;
     63                 return;
     64             }
     65             else
     66             {
     67                 pNode = pNode->pLeft;
     68             }
     69         }
     70         //相等  出错
     71         else
     72         {
     73             //释放临时节点空间
     74             free(pTemp);
     75             pTemp = NULL;
     76             return;
     77         }
     78     }
     79 }
     80 
     81 BiTree *CreateSBT(int arr[], int len)
     82 {
     83     BiTree *pRoot = NULL;
     84     int i;
     85 
     86     assert(arr!=NULL && len>0);
     87 
     88     for(i=0; i<len; ++i)
     89     {
     90         Add(&pRoot, arr[i]);
     91     }
     92 
     93     return pRoot;
     94 }
     95 
     96 void BiTreeTraversal(BiTree *pRoot)
     97 {
     98     if(NULL == pRoot)
     99     {
    100         return;
    101     }
    102     printf("%d ", pRoot->nValue);
    103     BiTreeTraversal(pRoot->pLeft);
    104     BiTreeTraversal(pRoot->pRight);
    105 }
    106 
    107 void FindNode(BiTree *pRoot, int nNum, BiTree **pDel, BiTree **pFather)
    108 {
    109     assert(pRoot!=NULL && pDel!=NULL && pFather!=NULL);
    110 
    111     while(pRoot != NULL)
    112     {
    113         if(nNum == pRoot->nValue)
    114         {
    115             *pDel = pRoot;
    116             return;
    117         }
    118         else if(nNum < pRoot->nValue)
    119         {
    120             *pFather = pRoot;
    121             pRoot = pRoot->pLeft;
    122         }
    123         else
    124         {
    125             *pFather = pRoot;
    126             pRoot = pRoot->pRight;
    127         }
    128     }
    129 }
    130 
    131 void DelNode(BiTree **ppRoot, int nNum)
    132 {
    133     BiTree *pDel = NULL;
    134     BiTree *pMark = NULL;
    135     BiTree *pFather = NULL;
    136 
    137     assert(*ppRoot!=NULL && ppRoot!=NULL);
    138 
    139     //查找
    140     FindNode(*ppRoot, nNum, &pDel, &pFather);
    141 
    142     //没找到
    143     if(NULL == pDel)
    144     {
    145         return;
    146     }
    147 
    148     //找到
    149     //检测节点情况
    150     //两个孩子
    151     while(pDel->pLeft!=NULL && pDel->pRight!=NULL)
    152     {
    153         //找到左的最右
    154         //先标记要删除节点
    155         pMark = pDel;
    156 
    157         //向左走一步
    158         pFather = pDel;
    159         pDel = pDel->pLeft;
    160 
    161         //最右
    162         while(pDel->pRight != NULL)
    163         {
    164             pFather = pDel;
    165             pDel = pDel->pRight;
    166         }
    167 
    168         //值覆盖
    169         pMark->nValue = pDel->nValue;
    170     }
    171 
    172     //一个孩子
    173     //被删除节点是根节点
    174     if(NULL == pFather)
    175     {
    176         *ppRoot = (*ppRoot)->pLeft?(*ppRoot)->pLeft : (*ppRoot)->pRight;
    177         free(pDel);
    178         pDel = NULL;
    179         return;
    180     }
    181 
    182     //被删除节点是父亲的左
    183     if(pDel == pFather->pLeft)
    184     {
    185         pFather->pLeft = pDel->pLeft?pDel->pLeft : pDel->pRight;
    186     }
    187     //被删除节点是父亲的右
    188     else
    189     {
    190         pFather->pRight = pDel->pRight?pDel->pRight : pDel->pLeft;
    191     }
    192     free(pDel);
    193     pDel = NULL;
    194 }
    195 
    196 int main(void)
    197 {
    198     int arr[] = {1, 7, 3, 4, 5, 6, 7};
    199     int len = sizeof(arr)/sizeof(arr[0]);
    200     BiTree *pRoot = CreateSBT(arr, len);
    201     BiTreeTraversal(pRoot);
    202     printf("
    ");
    203     DelNode(&pRoot, 4);
    204     BiTreeTraversal(pRoot);
    205 
    206     return 0;
    207 }
  • 相关阅读:
    2D ARPG开发之旅(1) 贴图(tilebased)地图的实现(上)贴图修改版
    Microsoft CRM 2011 出现“无法更改域登录名" 错误
    Microsoft CRM 2011 隐藏文件菜单中的”新建活动“菜单
    Microsoft CRM 2011 安装时出现“Could not find GUID for server, Global Catalog not found in forest xxx”的问题
    C#(面向对象)
    delegate(委托)
    ww
    SQL(存储过程,触发器,回滚)
    sss
    EXcel
  • 原文地址:https://www.cnblogs.com/chen-cai/p/7874950.html
Copyright © 2020-2023  润新知