排序树的删除节点

本文提供了一个使用C语言实现的二叉搜索树(BST)实例,包括插入、中序遍历及删除节点等功能。通过具体代码展示了如何创建、操作及维护一棵二叉树。

#include <stdio.h>
#include <stdlib.h>

typedef struct _Tree
{
 int nValue;
 struct _Tree* pLeft;
 struct _Tree* pRight;
}Tree;


void InsertTree(Tree** tree,int nInsertValue)
{
 if (*tree == NULL)
 {
  (*tree) = (Tree*)malloc(sizeof(Tree));
  (*tree)->nValue = nInsertValue;
  (*tree)->pLeft = NULL;
  (*tree)->pRight = NULL;
  return;
 }
 else       //  看这个值要放在左边还是右边
 { 
  //Tree* temp = (*tree);

  while(1)
  {
   if ((*tree)->nValue < nInsertValue)
   {
    if ((*tree)->pRight == NULL)
    {
     (*tree)->pRight = (Tree*)malloc(sizeof(Tree));
     (*tree)->pRight->nValue = nInsertValue;
     (*tree)->pRight->pLeft = NULL;
     (*tree)->pRight->pRight = NULL;
     return;
    }
    //(*tree) = (*tree)->pRight;
    tree = &((*tree)->pRight);
   }
   else
   {
    if ((*tree)->pLeft == NULL)
    {
     (*tree)->pLeft = (Tree*)malloc(sizeof(Tree));
     (*tree)->pLeft->nValue = nInsertValue;
     (*tree)->pLeft->pLeft = NULL;
     (*tree)->pLeft->pRight = NULL;
     return;
    }
    //(*tree) = (*tree)->pLeft;
    tree = &((*tree)->pLeft);
   }
  }
 }
}

 


void CreateTree(Tree** tree,int* arr,int nLength)
{
 for (int i=0;i<nLength;i++)
 {
  InsertTree(tree,arr[i]);
 }
}


void DeleteOneChild(Tree* pDel,Tree* pFather)
{
 //  看  要删除的节点  是放在  他父亲节点的左边还是右边
 if (pDel == pFather->pLeft)
 {
  //  让 左指针  指向 他不为空的那个子节点
  pFather->pLeft = pDel->pLeft?pDel->pLeft:pDel->pRight;
 }
 else
 {
  pFather->pRight = pDel->pLeft?pDel->pLeft:pDel->pRight;
 }
 free(pDel);
 pDel = NULL;
}

void FindTree(Tree* tree,int nFindValue,Tree** pDel,Tree** pFather)
{
 while(tree)
 {
  if (tree->nValue == nFindValue)
  {
   //  记住要删除的这个节点
   (*pDel) = tree;
   return;
  }
  else if (tree->nValue > nFindValue)    // 在左边查找
  {
   *pFather = tree;
   tree = tree->pLeft;
  }
  else
  {
   *pFather = tree;
   tree = tree->pRight;
  }
 }

 *pDel = NULL;
 *pFather = NULL;
}

void DeleteTree(Tree** tree,int nDeleteValue)
{
 if ((tree ==  NULL) || (*tree == NULL))
 {
  return;
 }
 Tree* pDel = NULL;
 Tree* pFather = NULL;

 //   查找要删除的节点
 FindTree(*tree,nDeleteValue,&pDel,&pFather);

 //  看是不是查找成功
 if(pDel == NULL)
 {
  return;
 }

 //  看  要删除的节点  有几个子节点
 if (pDel->pLeft != NULL && pDel->pRight != NULL)
 {
  Tree* bj = pDel;
  pFather = pDel;
  //  把它转换成 只有一个子节点的情况
  pDel = pDel->pRight;

  while(pDel->pLeft)
  {
   pFather = pDel;
   pDel = pDel->pLeft;
  } 
  
  //pDel  记住的就是要替换值的那个节点
  bj->nValue = pDel->nValue;
 }


 //  看要删除的是不是  根
 if (pFather == NULL)
 {
  (*tree) = pDel->pLeft?pDel->pLeft:pDel->pRight;
  free(pDel);
  pDel = NULL;
  return;
 }
 //  删除只有一个子节点
 DeleteOneChild(pDel,pFather);
}

void MidPrint(Tree* tree)
{
 if (tree)
 {
  MidPrint(tree->pLeft);
  printf("%d ",tree->nValue);
  MidPrint(tree->pRight);
 }
}


int main()
{

 int arr[10] = {5,6,2,3,1,9,8,0,7,4};

 Tree* tree = NULL;

 CreateTree(&tree,arr,10);
 
 MidPrint(tree);
 printf("\n");

 

 DeleteTree(&tree,0);

 MidPrint(tree);
 printf("\n");
 
 system("pause");
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值