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

#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 ;
}
时间: 2024-09-21 20:44:24

二叉搜索树非递归方式删除节点的相关文章

二叉搜索树的插入与删除(详细解析)_C 语言

题目:创建一个类,类中的数据成员时一棵二叉搜索树,对外提供的接口有添加结点和删除结点这两种方法.用户不关注二叉树的情况.要求我们给出这个类的结构以及实现类中的方法. 思路添加结点:添加结点其实很容易,我们只需要找到结点所行对应的位置就可以了,而且没有要求是平衡的二叉搜索树,因此每次添加结点都是在叶子结点上操作,不需要修改二叉搜索树整体的结构.要找出添加节点在二叉搜索树中的位置,可以用一个循环解决.判断插入结点与当前头结点的大小,如果大于头结点则继续搜索右子树,如果小于头结点则继续搜索左子树.直到

二叉搜索树与树的遍历非递归练习

复习了二叉搜索树的实现,包括插入.查找和删除操作,顺便做了下二叉树的三种遍历操作.全部操作采用非递归方式.   #include<iostream>   #include<stack>   using namespace std;     typedef int T;   // 值类型      // 节点定义    struct node {       T val;       node *left,*right;       node(const T& val):va

二叉搜索树的非递归创建和搜索

#include "stdio.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

Java创建二叉搜索树,实现搜索,插入,删除操作

Java实现的二叉搜索树,并实现对该树的搜索,插入,删除操作(合并删除,复制删除) 首先我们要有一个编码的思路,大致如下: 1.查找:根据二叉搜索树的数据特点,我们可以根据节点的值得比较来实现查找,查找值大于当前节点时向右走,反之向左走! 2.插入:我们应该知道,插入的全部都是叶子节点,所以我们就需要找到要进行插入的叶子节点的位置,插入的思路与查找的思路一致. 3.删除: 1)合并删除:一般来说会遇到以下几种情况,被删节点有左子树没右子树,此时要让当前节点的父节点指向当前节点的左子树:当被删节点

纸上谈兵: 树, 二叉树, 二叉搜索树[转]

树的特征和定义 树(Tree)是元素的集合.我们先以比较直观的方式介绍树.下面的数据结构是一个树: 树有多个节点(node),用以储存元素.某些节点之间存在一定的关系,用连线表示,连线称为边(edge).边的上端节点称为父节点,下端称为子节点.树像是一个不断分叉的树根. 每个节点可以有多个子节点(children),而该节点是相应子节点的父节点(parent).比如说,3,5是6的子节点,6是3,5的父节点:1,8,7是3的子节点, 3是1,8,7的父节点.树有一个没有父节点的节点,称为根节点(

纸上谈兵: 树, 二叉树, 二叉搜索树

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢!   树的特征和定义 树(Tree)是元素的集合.我们先以比较直观的方式介绍树.下面的数据结构是一个树: 树有多个节点(node),用以储存元素.某些节点之间存在一定的关系,用连线表示,连线称为边(edge).边的上端节点称为父节点,下端称为子节点.树像是一个不断分叉的树根. 每个节点可以有多个子节点(children),而该节点是相应子节点的父节点(parent).比如说,3,5

二叉搜索树的建立

二叉搜索树最大特征是:左边子结点的值<当前结点的值,右边子结点的值>当前结点的值. 依照这个特征,可以使用递归和非递归两种方式建立一颗二叉搜索树. 下面是我的代码,分明列举了递归和非递归的建立方式.最初写的代码与正确版本大致相同,但程序总是运行不通过,debug后发现问题在于指针操作错误.自以为对c语言非常熟稔了,但还是犯下如此幼稚的错误,所以贴出这个错误,作为一个警示. 2014/5/24 ps:原来二叉搜索树最难的地方在于删除操作,所以补充一个删除操作.此外,还明白了书本介绍二叉搜索树的原

算法起步之二叉搜索树

原文:算法起步之二叉搜索树         学习二叉搜索树之前,我们先复习一下树的相关知识,数是几种经典的数据结构之一,树其实就是维护了一对多的关系,一个节点可以有多个孩子,但是每个节点至多只有一个双亲.如何去描述存储一棵树呢,这里方法有很多,数组.链表.十字链表等等.这里我们主要研究二叉树,二叉树是树的一种特殊形式,节点至多只有两棵子树,有左右之分次序不能任意颠倒.二叉树还有一个性质就是叶子节点的个数=度为2的节点+1 .二叉搜索树又叫二叉排序树或二叉查找树.他比二叉树又加个1个性质,就是左子

【算法学习】AVL平衡二叉搜索树原理及各项操作编程实现(C++)

AVLTree即(Adelson-Velskii-Landis Tree),是加了额外条件的二叉搜索树.其平衡条件的建立是为了确保整棵树的深度为O(nLogn).平衡条件是任何节点的左右子树的高度相差不超过1.   在下面的代码中,编程实现了AVL树的建立.查找.插入.删除.遍历等操作.采用C++类封装. AVL树中比较复杂的操作时插入和删除操作.在这里对插入和删除操作进行讲解.   AVL树的插入操作 向AVL树中插入元素可能会导致树失去平衡.但是,我们只需要调整插入点至根节点的路径上不满足平