二叉搜索树

二叉搜索树的概念

二叉搜索树又称为二叉排序树,

因为它的特点是1.在根左边的树的每个节点都小于根

              2.在根右边的树的每个节点都于大根



二叉搜索树的操作

1. 查找

  PNode FindBST(PNode pRoot, DataType data)

{

assert(pRoot);

PNode pcur = pRoot;

while (pcur)

{

if (pcur->_data == data)//如果为当前节点,则

{

return pcur;

}

else if(pcur->_data > data)//当前节点大于要查找的点

{

pcur = pcur->_pLeft;

        }

else 

   pcur = pcur->_pRight;

}

}

2. 插入

 

int InsertBST(PNode* pRoot, DataType data)

{

PNode pcur = *pRoot;

assert(pRoot);

if (*pRoot == NULL)//二叉树为空

pRoot = BuyBSTreeNode(data);

PNode pcur = *pRoot;

PNode parent = *pRoot;

while (pcur)//找待插入的结点

{

if (pcur->_data == data)

{

return;//如果是,就返回

}

else if (pcur->_data > data)

{

parent = pcur;

pcur = pcur->_pLeft;

}

else

{

parent = pcur;

pcur = pcur->_pRight;

}

}

pcur = BuyBSTreeNode(data);//插入结点

if (data < parent->_data)

{

parent->_pLeft = pcur;

}

else if (data>parent->_data)

{

parent->_pRight = pcur;

}

}

3. 删除

删除可分为4种情况

1.要删除的结点没有左右子树(可以归纳到2和3中)

2.要删除的结点没有右子树

3.要删除的结点没有左子树

4.要删除的结点有左右子树

1)如果要删除的右孩子有左子树,关键在于找到替代的删除结点,例如删除5

2)如果要删除的点有右子树,将值替换掉,例如删除7

 

nt DeleteBSTree(PNode* pRoot, int data)

{

assert(pRoot);

if (NULL == pRoot)//为空

{

return;

}

PNode pcur = *pRoot;

PNode parent = *pRoot;

while (pcur)//找待删结点

{

if (pcur->_data == data)

{

break;

}

else if (pcur->_data > data)

{

parent = pcur;

pcur = pcur->_pLeft;

}

else

{

parent = pcur;

pcur = pcur->_pRight;

}

}

if (NULL == pcur)

{

return 0;

}

PNode pdel = *pRoot;

if (NULL == pcur->_pRight)//只有左子树或者是叶子结点

{

if (pcur == *pRoot)//要删除的是根节点

{

pdel = *pRoot;

*pRoot = (*pRoot)->_pLeft;

}

else if (pcur == parent->_pLeft)//只有左子树的结点

{

parent->_pLeft = pcur->_pLeft;

}

else // 叶子结点

parent->_pRight = pcur->_pRight;//即指向空

}

if (NULL == pcur->_pRight)//只有右子树或者是叶子结点

{

if (pcur == *pRoot)

{

pdel = *pRoot;

*pRoot = (*pRoot)->_pRight;

}

else if (pcur == parent->_pRight)

{

parent->_pRight = pcur->_pRight;

}

else

 

parent->_pLeft = pcur->_pLeft;

}

else//左右子树都存在

 

{

parent = pcur;

pdel = pcur->_pRight;//在右子树中找到所要替代的删除点

while (pdel->_pLeft)

{

parent = pdel;

pdel = pdel->_pLeft;

}

pcur->_data = pdel->_data;

 

if (pdel == parent->_pLeft)

parent->_pLeft = pdel->_pRight;

else//例如删除7

parent->_pRight = pdel->_pRight;

}

 

 

free(pdel);

}

二叉树的其他操作


void InitBSTree(PNode* pRoot)

{

assert(pRoot);

*pRoot = NULL;

}

void InOrderD(PNode pRoot)//中序

 

{  

if (pRoot)

 

{

 

InOrderD(pRoot->_pLeft);

 

printf("%c ", pRoot->_data);

 

InOrderD(pRoot->_pRight);

}

}

 

 

 

 

void DestroyBSTree(PNode* pRoot)//销毁

{

assert(pRoot);

if (*pRoot)//按照后序的方法销毁

{

DestroyBSTree((*pRoot)->_pLeft);

DestroyBSTree((*pRoot)->_pRight);

free(pRoot);

*pRoot = NULL;//指向空,不然会成为野指针

}

}

PNode BuyBSTreeNode(DataType data)

{

PNode pnewnode = (PNode) malloc(sizeof(node));

pnewnode->_pLeft = NULL;

pnewnode->_pRight = NULL;

pnewnode->_data = data;

 

}

头文件

#include"stdio.h"

#include"assert.h"

#include"malloc.h"

 

#ifndef  _BSTree_H__

#define _BSTree_H__

 

typedef char DataType;

 

typedef struct BSTreeNode

{

struct BinTreeNode* _pLeft;

struct BinTreeNode* _pRight;

DataType _data;

}node, *PNode;

 

 

 

void InitBSTree(PNode* pRoot);

int InsertBST(PNode* pRoot, DataType data);

PNode FindBST(PNode pRoot, DataType data);

int DeleteBSTree(PNode* pRoot, int data);

void InOrder(PNode pRoot);

void DestroyBSTree(PNode* pRoot);

PNode BuyBSTreeNode(DataType data);

 

 

#endif _BSTree_H__

 

测试函数

#include"BSTree.h"

 

int main()

{

PNode pRoot = NULL;

InitBSTree(& pRoot);

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

int size = sizeof(arr) / sizeof(arr[0]);

for (int i = 0; i < size; i++)

{

InsertBST(& pRoot, arr[i]);

}

InOrder(&pRoot);

 

FindBST(& pRoot, 6);

 

 

DeleteBSTree(& pRoot, 7);

InOrder(pRoot);

DeleteBSTree(&pRoot, 9);

InOrder(pRoot);

}

 

 

 

 

 

 

 

    

 

 

 


 

 

 

 

 

 

    

 

 

 


 

 

 

    

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值