/*
二叉搜索树: 1.每个数据都具有唯一的关键字
2.比根节点关键字打的放右边,小的放左边,所以每一次缩减都可以至少排除一半的数
3.二叉搜索树的每一个子树都是二叉搜索树
采用中序遍历进行排序,左,根,右
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//每一个节点的数据
typedef struct dataPair
{
int first; //关键字
char second[20]; //数据
}DATA,*LPDATA;
//二叉树结构体
ytpedef struct treeNode
{
DATA data;
struct treeNode*LChild;
struct treeNode*RChild;
}NODE,*LPNODE;
//封装一个二叉树组
typedef struct binarySearchTree
{
LPNODE root; //用根节点表示整个数组
int treeSize; //树中结点数
}BST,*LPBST;
//创建树
LPBST createBST()
{
LPBST tree = (LPBST)malloc(sizeof(BST));
tree->root = NULL;
tree->treeSize = 0;
return tree;
}
//创建节点
LPNODE createNode(DATA data)
{
LPNODE newNode = (LPNODE)malloc(sizeof(NODE));
newNode->data = data;
newNode->LChild = NULL;
newNode->RChild = NULL;
return newNode;
}
//万金油函数
int size(LPBST tree)
{
return tree->treeSize;
}
int empty(LPBST tree)
{
return tree->treeSize == 0;
}
//打印遍历
void printNode(LPNODE curNode)
{
printf("%d\t%s\n",curNode->data.first,curNode->data.second);
}
//中序遍历
void midOrder(LPNODE tree)
{
if(tree != NULL)
{
midOrder(tree->LChild); //通过循环midOrder函数,实现重复寻找
printNode(tree);
midOrder(tree->RChild);
}
}
//插入节点
void insertNode(LPBST tree,DATA data)
{
//插入的话,找到叶子结点就可以了,通过关键字比较大小
LPNODE newNode = createNode(data);
//找合适的位置插入
LPNODE pMove = tree->root;
LPNODE pMoveParent = NULL; //记录空NULL 的上一个节点,只有找到最末尾的下一个NULL(空)才找到最后的节点
while(pMove != NULL)
{
pMoveParent = pMove; //记录移动节点的父结点,即pMove上一个结点
if(data.first < pMove->data.first)
{
pMove = pMove->LChild;
}
else if(data.first>pMove->data.first)
{
pMove = pMove->RChild;
}
else
{
//修改相同关键字的结点的数据
strcpy(pMove->data.second,data.second)
return;
}
}
//退出循环,找到了合适的位置
if(tree->root == NULL) //一次都不循环
{
tree->root = newNode;
}
else
{
//判断pMoveParent插在pMove的左边还是右边
if(pMoveParent->data.first > data.first)
{
pMoveParent->LChild = newNode; //插入的节点数据比根部小,插在左边
}
else
{
pMoveParent->RChild = newNode; //比根部大,插在右边
}
}
}
tree->treeSize++;
}
//查找,通过关键字去查找
LPNODE searchBST(LPNODE tree,int first)
{
LPNODE pMove = tree->root;
if(pMove == NULL)
return pMove;
else
{
while(pMove->data.first != first)
{
if(pMove->data.first > first)
{
pMove = pMove->LChild;
}
else
{
pMove = pMove->RChild;
}
if(pMove == NULL)
return pMove;
}
return pMove;
}
}
//二叉搜索树的删除,先删除根节点,是需要调整的,一种是:从左子树中找根节点左边最大的数放上去;另一种是:从右子树最左边把根节点右边最小的数放上去
void erase(LPBST tree,int first)
{
//删除根节点,必定会影响父结点,和孩子节点(根节点,左子树结点,右子树结点全部的指针都要保存),所以需要去保存影响的节点,在这里创建新的节点为连接方式
LPNODE pMove = tree->root;
LPNODE pMoveParent = NULL;
while(pMove != NULL && pMove->data.first != first)
{
pMoveParent = pMove;
if(first < pMove->data.first)
{
pMove = pMove->LChild; //往左边寻找
}
else if(first > pMove->data.first)
{
pMove = pmove->RChild;
}
else
break;
}
if(pMove == NULL)
{
printf("没有找到指定位置,无法删除");
system("pause");
return;
}
//删除节点的左右子树都存在,我们要找左子树的最右边放上去,因为左子树最右边的数是最大的,如果不是它,就不能完成按大小顺序排列
if(pMove->LChild != NULL && pMove->RChild != NULL)
{
//找最右边放上去,moveNode为移动的指针,moveNodeParent为moveNode的父结点
LPNODE moveNode = pMove->LChild;
LPNODE moveNodeParent = pMove;
//找最右边放上去,如果不等于空,就等于还没有找到删除节点的左子树的最右边,要往下走
while(moveNode->RChild != NULL)
{
moveNodeParent = moveNode;
moveNode = moveNode->RChild;
}
LPNODE newNode = createNode(moveNode->data);
newNode->LChild = pMove->LChild;
newNode->RChild = pMove->RChild; //保存pMove删除结点的左右子树
//分类讨论删除的节点
if(pMoveParent == NULL) //删除的是根节点
tree->root = newNode;
else if(pMove == pMoveParent->LChild)
pMoveParent->LChild = newNode;
else
pMove->RChild = newNode;
//调整二叉树
if(moveNodeParent == pMove)
{
pMoveParent = newNode;
}
else
{
pMoveParent = moveNodeParent;
}
free(pMove);
pMove = moveNode;
}
LPNODE sNode = NULL;
//如果删除结点左右存在节点,保存删除结点的下一个节点
if(pMove->LChild != NULL)
sNode = pMove->LChild;
else
sNode = pMove->RChild;
if(tree->root == pmove)
{
tree->root = sNode;
}
else
{
if(pMove == pMoveParent->LChild)
{
pMoveParent->LChild = sNode;
}
else
{
pMoveParent->RChild = sNode;
}
}
free(pMove);
tree->treeSize--;
}
int main()
{
LPBST tree = createBST();
DATA array[8] = { 50 ,"明", 10 ,"其",80,"鬼",30,"五",60,"死",55,"卡尔",45,"冥王",20,"鬼王"};
for(int i=0;i<8;i++)
{
insertNode(tree,aray[i]);
}
printf("中序遍历结果:\n");
midOrder(tree->root);
//输出结果,按数字大小进行排序
printf("查找55:");
printNode(searchBST(tree,55)); //查找到的是 “卡尔”
erase(tree,30);
midOrder(tree->root);
printf("\n");
system("pause");
return 0;
}
二叉搜索树
最新推荐文章于 2024-12-10 08:26:49 发布