介绍:
二叉排序树的特点为:根节点的左子树所有节点关键字都要小于根节点关键字,右子树所有节点关键字都要大于等于根节点关键字;且对任意充当根节点的节点都满足
其时间复杂度和树的均衡程度有关,树的分支越均衡则事件复杂度越低
即与树的深度有关,最好的情况下为O(log2,n)
最差的情况为单支树,O(n)
则根据时间复杂度可引入平衡二叉树,即
对于每个节点都设立bf因子,bf=左子树深度-右子树深度
只有每个节点bf的绝对值都<=1时,该二叉排序树为平衡二叉树
失衡二叉树:
当对一个平衡二叉树插入新的节点时,可能会导致树的失衡
对失衡节点可分为:
1.LL 2.LR 3.RL 4.RR
可按照二叉排序树的性质调整,即将失衡的三个节点最小的做左子节点,
最大的做右子节点,另外一个做根节点
实现
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define KeyType int
typedef struct {
KeyType key;
//···其他数据域
}ElemType;
typedef struct BSTNode {
ElemType data;
BSTNode* rchild;
BSTNode* lchild;
}BSTNode;
/*二叉排序树查找---递归形式*/
BSTNode* SearchBST(BSTNode* tree, KeyType key) {
if (!tree || tree->data.key == key)
return tree;//若树为空或树的数据域关键字与要查找的相同则返回
else {
if (tree->data.key > key)
return SearchBST(tree->lchild, key);//若树的数据域关键字过大则继续对其左子树查找
else
return SearchBST(tree->rchild, key);//若树的数据域关键字过小则继续对其右子树查找
}
}
/*初始化二叉排序树*/
BSTNode* InitBST(KeyType key) {
BSTNode* T = (BSTNode*)malloc(sizeof(BSTNode));
T->lchild = T->rchild = NULL;
T->data.key = key;
return T;
}
/*二叉排序树插入---递归形式*/
void InsertBST(BSTNode** tree, KeyType key) {
if ((*tree)->data.key > key) {//如果二叉树当前节点数据关键字大于插入关键字,则将在其左子树插入
if (!(*tree)->lchild) {//若当前左子节点为空,则直接插入
BSTNode* T = (BSTNode*)malloc(sizeof(BSTNode));
T->data.key = key;
T->lchild = T->rchild = NULL;
(*tree)->lchild = T;
}
else//若当前左子节点不为空则递归
InsertBST(&((*tree)->lchild), key);
}
else if ((*tree)->data.key <= key) {
if (!(*tree)->rchild) {
BSTNode* T = (BSTNode*)malloc(sizeof(BSTNode));
T->data.key = key;
T->lchild = T->rchild = NULL;
(*tree)->rchild = T;
}
else
InsertBST(&((*tree)->rchild), key);
}
}
/*二叉树遍历---中序遍历*/
void TraverseBST(BSTNode* tree) {
if (tree) {
printf("%3d", tree->data.key);
TraverseBST(tree->lchild);
TraverseBST(tree->rchild);
}
}
int main() {
KeyType key;
printf("\n插入信息>>\n");
scanf("%d", &key);
BSTNode* tree = InitBST(key);
while (1) {
printf("\n插入信息(退出请输入999)>>\n");
scanf("%d", &key);
if (key == 999)
break;
InsertBST(&tree, key);
}
printf("中序遍历>>");
TraverseBST(tree);
return 0;
}
实现思想:
首先建立一个插入函数,设置形参:指向根节点地址的指针(因为要对传入的这个节点身上发生变化),和要插入的关键字数据。随后判断该关键字和根节点的关键字的大小;若小于则再观察右子节点是否为空,若为空直接插入,否则就再对这个右子节点进行递归,一直找到能插入的空节点为止。当大于时,同理对左子树。