zoukankan      html  css  js  c++  java
  • 排序二叉树的建立,查询与删除

    因为排序二叉树的有序性,建立与查询都不是很难,唯一的难点是删除结点的操作,删除节点且要保证该树仍为二叉树且仍满足有序的性质

    二叉树的删除操作主要有三种情况:

    • 所删除的节点是叶子节点,这样就可以先遍历这个树,然后找到需要删除的节点,把它free掉就好
    • 所删除的节点只有一个左子结点,或者只有一个右子结点,则把该节点的子结点变为它父结点的子结点 ,然后free掉这个结点
    • 就是最麻烦的一类,删除的结点既有左子结点又有右子结点,这时,我们的处理方式是,用左子树的最右结点,就是值最大那个叶节点的值覆盖掉要删除的结点,并free掉那个叶子节是

    具体实现代码如下:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <string>
      6 #include <queue>
      7 #include <vector>
      8 #include <cmath>
      9 #include <iomanip>
     10 #include <malloc.h>
     11 
     12 #define INF 0x3f3f3f3f
     13 #define FRER() freopen("in.txt", "r", stdin)
     14 #define FREW() freopen("out.txt", "w", stdout)
     15 
     16 using namespace std;
     17 
     18 typedef struct node {
     19     int nValue;
     20     struct node *pLeft;
     21     struct node *pRight;
     22 }BinaryTree;
     23 
     24 void InsertNode(BinaryTree **pTree, int nNum) {
     25     BinaryTree *pTemp = NULL;
     26     pTemp = (BinaryTree*)malloc(sizeof(BinaryTree));
     27     pTemp->nValue = nNum;
     28     pTemp->pLeft = NULL;
     29     pTemp->pRight = NULL;
     30 
     31     //空树
     32     if(*pTree == NULL) {
     33         *pTree = pTemp;
     34         return ;
     35     }
     36 
     37     //非空树
     38     BinaryTree *pNode = *pTree;
     39     while(1) {
     40         if(nNum > pNode->nValue) {
     41             //去右侧
     42             if(pNode->pRight == NULL) {
     43                 pNode->pRight = pTemp;
     44                 return;
     45             }
     46 
     47             //向右走
     48             pNode = pNode->pRight;
     49         }
     50         else if(nNum < pNode->nValue) {
     51             //去左侧
     52             if(pNode->pLeft == NULL) {
     53                 pNode->pLeft = pTemp;
     54                 return ;
     55             }
     56 
     57             //向左走
     58             pNode = pNode->pLeft;
     59         }
     60         //相等
     61         else {
     62             free(pTemp);
     63             pTemp = NULL;
     64             return ;
     65         }
     66     }
     67 }
     68 
     69 void CreateBST(int arr[], int nLength, BinaryTree **pTree) {
     70     if(arr == NULL || nLength <= 0)
     71         return ;
     72     for(int i = 0; i < nLength; ++i) {
     73         InsertNode(pTree, arr[i]);
     74     }
     75 }
     76 
     77 void BiTreeTreavelsal(BinaryTree *pNode) {
     78     if(pNode == NULL) return ;
     79     printf("%d ", pNode->nValue);
     80     BiTreeTreavelsal(pNode->pLeft);
     81     BiTreeTreavelsal(pNode->pRight);
     82 }
     83 
     84 void Search(BinaryTree *pTree, int nNum, BinaryTree **pDel, BinaryTree **pFather) {
     85     while(pTree != NULL) {
     86         if(pTree->nValue == nNum) {
     87             *pDel = pTree;
     88             return ;
     89         }
     90         else if(pTree->nValue > nNum) {
     91             *pFather = pTree;
     92             pTree = pTree->pLeft;
     93         }
     94         else {
     95             *pFather = pTree;
     96             pTree = pTree->pRight;
     97         }
     98     }
     99 }
    100 
    101 void DelNode(BinaryTree **pTree, int nNum) {
    102     if(*pTree == NULL) return ;
    103     
    104     //查找
    105     BinaryTree *pDel = NULL;
    106     BinaryTree *pFather = NULL;
    107 
    108     Search(*pTree, nNum, &pDel, &pFather);
    109 
    110     //二叉树上没有该点
    111     if(pDel == NULL) return ;
    112 
    113     BinaryTree *pMark = NULL;
    114     if(pDel->pLeft != NULL && pDel->pRight != NULL) {
    115         
    116         //找左的最右
    117         pMark = pDel;
    118 
    119         //向左走一步
    120         pFather = pDel;
    121         pDel = pDel->pLeft;
    122         
    123         while(pDel->pRight != NULL) {
    124             pFather = pDel;
    125             pDel = pDel->pRight;
    126         }
    127 
    128         //值覆盖
    129         pMark->nValue = pDel->nValue;
    130     }
    131 
    132     //被删除的结点是根结点
    133     if(pFather == NULL) {
    134         *pTree = pDel->pLeft ? pDel->pLeft : pDel->pRight;
    135         free(pDel);
    136         pDel = NULL;
    137         return ;
    138     }
    139 
    140     //被删除的结点不是根结点
    141     if(pDel == pFather->pLeft) {
    142         pFather->pLeft = pDel->pLeft ? pDel->pLeft : pDel->pRight;
    143         free(pDel);
    144         pDel = NULL;
    145         return ;
    146     }
    147     else {
    148         pFather->pRight = pDel->pLeft ? pDel->pLeft : pDel->pRight;
    149         free(pDel);
    150         pDel = NULL;
    151         return ;
    152     }
    153 }
    154 
    155 int main()
    156 {
    157     int arr[] = {10,38,2,100,80,15,1,8,16};
    158     BinaryTree *pTree = NULL;
    159     CreateBST(arr,sizeof(arr)/sizeof(arr[0]),&pTree);
    160     BiTreeTreavelsal(pTree);
    161     printf("
    ");
    162     DelNode(&pTree,10);
    163     BiTreeTreavelsal(pTree);
    164     return 0;
    165 }
  • 相关阅读:
    Dubbo架构设计及原理详解
    Zookeeper+Dubbo+SpringMVC环境搭建
    Java 延迟队列使用
    深入理解Spring Redis的使用 (九)、通过Redis 实现 分布式锁 的 BUG,以及和数据库加锁的性能测试
    深入理解Spring Redis的使用 (八)、Spring Redis实现 注解 自动缓存
    深入理解Spring Redis的使用 (七)、Spring Redis 使用 jackson序列化 以及 BaseDao代码
    深入理解Spring Redis的使用 (六)、用Spring Aop 实现注解Dao层的自动Spring Redis缓存
    深入理解Spring Redis的使用 (五)、常见问题汇总
    深入理解Spring Redis的使用 (四)、RedisTemplate执行Redis脚本
    深入理解Spring Redis的使用 (三)、使用RedisTemplate的操作类访问Redis
  • 原文地址:https://www.cnblogs.com/fan-jiaming/p/9965790.html
Copyright © 2011-2022 走看看