原理
二叉排序树也叫二叉查找树或者是一颗空树。
特点
- 若左子树非空,则左子树上所有结点的值均小于根节点的值
- 若右子树非空,则右子树上所有结点的值均大于根节点的值
- 左右子树也分别是一颗二叉树
步骤
1、新建一颗二叉树
2、对建好的二叉树进行中序遍历输出
3、对二叉树进行查找
-二叉树的最大查找次数是树的高度,相关内容可以看(六)数据结构–二叉树相关内容
代码整理
#include <stdio.h>
#include <stdlib.h>
typedef int keyType;
typedef struct BSTNode{
keyType key;
struct BSTNode *lchild, *rchild;
}BSTNode, *BiTree;
// 54 20 66 40 28 79 58
// 初始化树
void init_BST(BiTree &Tree, keyType* str, int len){
for (int i = 0; i < len; i++) {
BST_Insert(Tree, str[i]);
}
}
// 中序遍历
void inOrder(BiTree Tree){
if (Tree!=NULL){
inOrder(Tree->lchild);
printf("%3d",Tree->key); //打印
inOrder(Tree->rchild);
}
}
int main() {
// 定义Tree
BiTree Tree=NULL;
BiTree Search;
// 将要写进二叉排序数的元素值
keyType str[7]={54,20,66,40,28,79,58};
init_BST(Tree, str, 7);
inOrder(Tree); // 有小到大排序
printf("\n");
// 查找
BiTree search,parent;
search=BST_Search(Tree, 40, parent);
printf("%d\n",Search);
DeleteNode(Tree, 54);
inOrder(Tree);
return 0;
}
建树
// 插入树
int BST_Insert(BiTree &Tree, keyType k){
// 给进来的新结点申请空间
BiTree TreeNew= (BiTree)calloc(1,sizeof(BSTNode));
TreeNew->key=k; // 赋值
if(Tree==NULL){
Tree=TreeNew;
return 0;
}
BiTree p=Tree,parent; // 用来查找树
while (p){
parent=p;
if(k > p->key){
p=p->rchild;
} else if (k < p->key){
p=p->lchild;
} else {
return -1; // 相等元素不放入查找数
}
}
// 判断放到父亲的左边还是右边
if (k > parent->key){
// 新结点放到父亲右边
parent->rchild=TreeNew;
} else {
// 新结点放到父亲左边
parent->lchild=TreeNew;
}
}
查找树
// 查找树
BiTree BST_Search(BiTree Tree, keyType key, BiTree &parent){
parent=NULL;
while (Tree!=NULL&&key!=Tree->key){
parent=Tree;
if(key < Tree->key){
Tree=Tree->lchild;
} else{
Tree=Tree->rchild;
}
}
return Tree;
};
删除树
// 删除树
int DeleteNode(BiTree &Tree, keyType key){
if (Tree==NULL){
return -1;
}
if (Tree->key > key){ //当前结点的值大于要删除的值
DeleteNode(Tree->lchild,key);
} else if (Tree->key < key){ // 当前结点的值小于要删除的值
DeleteNode(Tree->rchild,key);
} else { // 找到要删除的结点时
// 如果左右孩子都为空,相当于顶上去一个空结点,所以可以走两个判断中的任意一个
if (Tree->lchild==NULL){ // 判断如果左孩子为空
BiTree tempNode=Tree; // 用临时变量接当前结点
Tree=Tree->rchild; // 因为只有左孩子为空,删除当前结点相当于把右孩子直接顶上去
free(tempNode); // 释放
} else if (Tree->rchild==NULL){ // 判断如果右孩子为空,原理同左孩子为空一样
BiTree tempNode=Tree;
Tree=Tree->lchild;
free(tempNode);
} else { // 如果左右孩子都不为空
// 找替代值,一般是左子树的最右侧结点,或者右子树的最左测结点
BiTree tempNode=Tree->lchild; // 用临时变量接当前结点
while (tempNode->rchild!=NULL){
tempNode=tempNode->rchild;
}
// 把tempNode对应的值替换到要删除的值的位置上
Tree->key=tempNode->key;
// 在左子树中找到tempNode的值,删除
DeleteNode(Tree->lchild,tempNode->key);
}
}
}