二叉搜索树的概念
二叉搜索树又称为二叉排序树,
因为它的特点是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);
}