二叉搜索树非递归方式删除节点

简介: #include "stdio.h"#include "iostream.h"typedef struct node{ int data ; node*lChild ; node*rChild ;}TreeNode ;void Insert(TreeNode**root,i...
#include "stdio.h"
#include "iostream.h"
typedef struct node
{
 int data ;
 node*lChild ;
 node*rChild ;
}TreeNode  ;
void Insert(TreeNode**root,int data)  //向二叉查找树中插入元素  采用非递归思想
{      
 TreeNode * p=*root ;//获得根结点 
 TreeNode*q=new TreeNode ;//分配一个要插入的新节点 
 q->lChild=q->rChild=NULL ; //新分配节点的左节点=右节点等于NULL
 q->data=data ;  //保存数据到节点    
 TreeNode *parent =p ; //用于保存父节点 
 while(p!=NULL)  //循环搜索节点  
 {
  parent=p ;  //首先parent指向root节点 
  if(p->data>data)   //如果节点数据大于当前节点
   p=p->lChild  ;//如果插入数据小于 节点数据那么指向左节点  我么最终是要找到一个NULL节点 
  else
   p=p->rChild  ;
 }
 //如果因为parent总是指向NULL节点的父节点 ,所以parent指向的节点不会为空,如果为空那么说明该树是一颗空的树。
 if(parent==NULL) 
  *root=q ; //将分配的节点作为根节点 
 else if(parent->data>data)
  parent->lChild=q ;   //<root左插
 else
  parent->rChild=q ;  //>root右插
} 

void InOrder(TreeNode*root)
{
 if(root!=NULL)
 {
  InOrder(root->lChild) ;
  printf("%d ",root->data) ;
  InOrder(root->rChild) ;
 }
}
bool   Find(TreeNode*root,int fData)   //非递归方法查询
{
 if(root==NULL)
  return false ;  //搜索树为空返回false  
 while(root!=NULL)
 {  
  if(root->data==fData)
   return true ;  
  if(root->data>fData)
   root=root->lChild ;
  else
   root=root->rChild ;  
 }
    
 return false  ;
}


void BST_Delete(TreeNode**tp ,int dData)   //删除节点 
{   
 TreeNode*root=*tp ;
    TreeNode* parent =NULL ;//父指针用来表示 是否是根节点  
 while(root!=NULL)  {  //循环查找
  if(dData<root->data)  //如果删除节点小于根节点数据
  {
   parent=root ;   //保存前一个节点的指针 
   root=root->lChild   ;  //dData小于root数据 那么查找左子树 

  } 
  else if(dData>root->data)
  {
   parent=root   ;
   root=root->rChild  ; //大于root数据那么查找右节点
 

  }
  else     //这里找到了节点 如果即不大于 节点数据 也不小于节点数据 并且节点不是NULL那就说明了 节点查找到了 ,揭晓来我们就需要判断节点并删除了。
  {        
   
   if(root->lChild==NULL&&root->rChild==NULL)  //是叶子节点  1、根节点    2、非根节点
   {
    if(parent==NULL)  //因为parent是NULL说明没有根节点   否则parent是不可能为NULL的
    {
     delete root  ;//直接删除根节点 
     root=NULL ;
        *tp=NULL ; 
     return ; //直接返回
    }
    else    //如果是非根节点的叶子节点  
    {  
     (parent->lChild==root)?(parent->lChild=NULL):(parent->rChild=NULL)  ;  //判断删除节点是parent的left还是right  
     delete root ;
     return  ;//对于叶子节点可以直接返回
     
    }
    
   }
   else if(root->lChild==NULL&&root->rChild!=NULL)  //待删除节点只有有孩子 情况和上面类似 
   { 
    if(parent==NULL)  //如果在是根节点 并且有右孩子的情况下 
    {
     *tp=root->rChild  ;//只有右孩子 那么指针移动到右孩子  保存到tp
     delete root ;  
     return ;
    }
    else
    {  
     (parent->lChild==root)?(parent->lChild=root->rChild):(parent->rChild=root->rChild) ; //令parent的left或者right指向 root的left
     delete root;
     return ;
    }
   }
   else  if(root->lChild!=NULL&&root->rChild==NULL)  //待删除节点只有左孩子 情况和上面类似 
   {
         
    if(parent==NULL)  //如果在是根节点 并且有右孩子的情况下 
    {
     *tp=root->lChild  ;//待删除节点只有左孩子 那么指针移动到左孩子
     delete root ;
     return ;
    }
    else
    {
     (parent->lChild==root)?(parent->lChild=root->lChild):(parent->rChild=root->lChild) ; //令parent的left或者right指向 root的left
     delete root ;
     return ;
    }
    
   }
   else  //最后一种  删除节点既有做孩子又有右孩子
   {
                   TreeNode  *p=root->lChild ;//定义一个p保存当前删除节点 我们利用这个节点左孩子找到最右下节点  。
                   while(p->rChild!=NULL)
       {
        parent=p ;  //保存右下节点的父节点指针
        p=p->rChild  ;//从待删除节点
       
       } 
       root->data=p->data ;
       parent->rChild=p->lChild ;
       delete p ;
      return ; 

   }
   
   
  }  
  
 
  
 }
 
}
int main(int argc,char*argv[])
{
 
    TreeNode *root=NULL;  //如果根节点指针在局部那么一定要初始化NULL否则程序崩溃 ,如果我们的指针是在全局定义的可以不初始化NULL全局变量放在静态存储区
 int a[]={32,36,15,53,18,45,72,48,16,93} ;
 for(int i=0;i<10;i++)
  Insert(&root,a[i]) ; 
 InOrder(root) ; 
 printf("\n") ;
 if(Find(root,0)) 
  printf("数据0找到\n") ;
 else
  printf("没有0数据\n") ;
    BST_Delete(&root,36) ;
 InOrder(root) ;  


 return 1 ;
}

目录
相关文章
|
Linux 编译器 C++
C/C++性能优化:从根本上消除拷贝操作的浪费
C/C++性能优化:从根本上消除拷贝操作的浪费
1489 1
|
8月前
|
人工智能 自然语言处理 架构师
字节面试: es怎么提升性能和精准度?(尼恩独家,史上最全)
本文由40岁老架构师尼恩撰写,针对ES(Elasticsearch)提升搜索性能和精准度的面试题进行详细解析。文章首先指出,提升ES速度和精准度是两个独立的问题,分别涉及性能优化和精准度优化。这些内容不仅有助于应对面试中的难题,还能帮助开发者在实际项目中构建更高效的搜索系统。尼恩强调,掌握这些知识后可以在面试中“吊打”面试官,轻松获得理想Offer。同时,他还提供了《尼恩Java面试宝典PDF》等资源供读者学习参考。
|
存储 分布式计算 安全
HDFS分布式文件系统架构原理详解
HDFS(Hadoop Distributed File System)是Hadoop核心组成之一,是分布式计算中数据存储管理的基础,被设计成适合运行在通用硬件上的分布式文件系统。HDFS架构中有两类节点,一类是NameNode,又叫“元数据节点”,另一类是DataNode,又叫“数据节点”,分别执行Master和Worker的具体任务。HDFS是一个(Master/Slave)体系结构,“一次写入,多次读取”。HDFS的设计思想:分而治之—将大文件、大批量文件分布式存放在大量独立的机器上。
HDFS分布式文件系统架构原理详解
|
SQL 人工智能 安全
网络安全漏洞与防御策略
在数字化时代,网络安全成为维护信息安全的关键防线。本文将探讨网络安全中常见的漏洞类型、加密技术的应用以及提升安全意识的重要性。通过分析具体案例,我们将了解如何识别和防御网络威胁,并强调个人与企业在构建网络安全体系中的作用。
|
前端开发 JavaScript Python
【Django跨域】一篇文章彻底解决Django跨域问题!
还有人不会用Django配置CORS? 耗时3600秒整理的资料直接拿走!一篇文章彻底解决Django跨域问题! 本文包含以下内容:Django解决跨域问题,Django解决跨域携带Cookie问题等。
4856 0
|
机器学习/深度学习 算法 数据挖掘
【机器学习实战】K- 近邻算法(KNN算法)
【机器学习实战】K- 近邻算法(KNN算法)
512 0
【机器学习实战】K- 近邻算法(KNN算法)
|
前端开发
【SpringMVC】SpringMVC配置拦截器 mvc:exclude-mapping 报错
转载请注明出处:http://blog.csdn.net/qq_26525215 本文源自【大学之旅_谙忆的博客】 今天写SpringMVC的拦截器的时候,遇到这样一个错误, Element mvc:exclude-mapping is not allowed here. 经过一番搜索,找到了原因。
2156 0
|
Java Android开发
eclipse报错GC overhead limit exceed,卡顿
在使用Eclipse的Build Project功能时,提示以下错误: An internal error occurred during: “Build Project”. GC overhead limit exceeded 如图: 搜索的一下,是属于java.lang.OutOfMemoryError。
1527 0
|
关系型数据库 MySQL 数据库
Windows 8.1下 MySQL绿色版安装配置与使用
原文:Windows 8.1下 MySQL绿色版安装配置与使用  Mysql-5.6.17-winx64操作步骤: 一、安装MySQL数据库 1、下载。      下载地址:http://downloads.mysql.com/archives/get/file/mysql-5.6.17-winx64.zip。
1456 0