次优查找树的原理是通过构造一棵二叉查找树来使每个键的期望搜索代价最小。次优查找树的优点在于能够以期望O(logn)的时间内查找一个键值,并且在数据量较大时仍能保持较高的查找效率。然而,由于构造该树需要大量复杂的计算,因此它并不适用于动态变化的数据集合。
一、次优查找树的原理是什么
次优查找树(Optimal Binary Search Tree)也称为带权二叉查找树(Weighted Binary Search Tree),是一种用于快速查找具有不同概率的键值的数据结构。该数据结构通过构造一个二叉查找树来使每个键的期望搜索代价最小。次优查找树的优点在于能够以期望O(logn)的时间内查找一个键值,并且在数据量较大时仍能保持较高的查找效率。然而,由于构造该树需要大量复杂的计算,因此它并不适用于动态变化的数据集合。
二、次优查找树简介
次优查找树是折半查找的一种一般形式,其理论基础是“被查找的各元素是不等概的”,而折半查找就是等概的,我们在使用中默认了这一性质。
用折半查找时,应该首先比较最中间的关键字,如果比对成功,查找结束。如果待查关键字小于查找表中关键字,就继续在左边的部分里进行折半查找;反之,在右边查找。但是,这是建立于各元素出现概率相同的情况下。如果各元素出现的概率,或者说权重不一样呢?这时,优异查找树的查找效率是较高的。可是鱼与熊掌不可兼得,优异查找树的构造太费时间,所以此时需要个折衷的方案,使得构造树不那么复杂,但查找效率又比折半查找高,这就是次优查找树的来历。
可以用以下代码构造次优查找树:
void build_SecondOptimal(BiTree&T,float sw[],int low,int high){
int i=low;
float min=abs(sw[high]-sw[low]);
//计算SW(h)-SW(l-1)
float dw=sw[high]+sw[low-1];
int j;
for(j=low+1;j<=high;j++){
if(abs(dw-sw[j]-sw[j-1])<min){
i=j;
min=abs(dw-sw[j]-sw[j-1]);
}
}
if(T==NULL)T=new bitree();
T->data=array[i];
if(i==low){
T->lchild=NULL;
}else{
build_SecondOptimal(T->lchild,sw,low,i-1);
}
if(i==high){
T->rchild=NULL;
}else{
build_SecondOptimal(T->rchild,sw,i+1,high);
}
}
三、二叉查找树简介
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势;所以应用十分广泛,例如在文件系统和数据库系统一般会采用这种数据结构进行高效率的排序与检索操作。
二叉搜索树(BST)又称二叉查找树或二叉排序树。一棵二叉搜索树是以二叉树来组织的,可以使用一个链表数据结构来表示,其中每一个结点就是一个对象。一般地,除了key和位置数据之外,每个结点还包含属性lchild、rchild和parent,分别指向结点的左孩子、右孩子和双亲(父结点)。如果某个孩子结点或父结点不存在,则相应属性的值为空(NULL)。根结点是树中少数父指针为NULL的结点,而叶子结点的孩子结点指针也为NULL。
设x是二叉搜索树中的一个结点。如果y是x左子树中的一个结点,那么y.key≤x.key。如果y是x右子树中的一个结点,那么y.key≥x.key。
在二叉搜索树中:
- 若任意结点的左子树不空,则左子树上所有结点的值均不大于它的根结点的值。
- 若任意结点的右子树不空,则右子树上所有结点的值均不小于它的根结点的值。
- 任意结点的左、右子树也分别为二叉搜索树。
延伸阅读1:二叉查找树的结构
二叉搜索树是能够高效地进行如下操作的数据结构。
- 插入一个数值
- 查询是否包含某个数值
- 删除某个数值