文字描算

  之前分析顺序查找和折半查找的算法性能都是在“等概率”的前提下进行的,但是如果有序表中各记录的查找概率不等呢?换句话说,概率不等的情况下,描述查找过程的判定树为何类二叉树,其查找性能最佳?

  如果只考虑查找成功的情况,则使查找性能达最佳的判定树是其带权内路径长度之和PH值取最小的二叉树。

  其中n为二叉树上结点的个数(即有序表的长度);hi为第i个结点在二叉树上的层次数;结点的权wi=cpi(i=1,2,…,n),其中pi为结点的查找概率,c为某个常量。称PH值取最小的二叉树为静态最优查找树。由于构造静态最优查找树代价较高,在此介绍一种构造近似最优查找树的有效算法。该算法的过程描述如下:

  已知一个按关键字有序的记录序列,其中, 与每个记录相应的权值为

  首先在记录序列中取第i(l<=i && i<=h)个记录构造根结点,使得取最小值,然后分别对子序列构造两棵次优查找树,并分别设为根结点的左子树和右子树。

示意图

算法分析

  从次优查找树的结构特定可知,其查找过程类似于折半查找。查找过程和二叉排序树算法类型,待二叉排序树会讲。由于查找过程是走了一条从根到待查记录所在节点(或叶子结点)的一条路径,进行过比较的关键字个数不超过树的深度,因此,次优查找树的平均查找长度和logn成正比。可见,在记录的查找概率不等时,可用次优查找树表示静态查找表,故又称为静态树表。

另外,大量实验表明,次优查找树和最优查找树的查找性能之差仅仅为1%-2%,很少查过3%,而且构造次优查找树的算法的时间复杂度为nlogn。

代码实现

 #include <stdio.h>
#include <stdlib.h>
#include <string.h> #define DEBUG
#define EQ(a, b) ((a)==(b))
#define LT(a, b) ((a)< (b))
#define LQ(a, b) ((a)<=(b))
#define MAX_SIZE 50 typedef char KeyType;
//数据元素类型
typedef struct{
//关键字
KeyType key;
//权值
int weight;
}ElemType;
//静态查找表
typedef struct{
//数据元素存储空间基址,0号单元留空
ElemType *elem;
//表长度
int length;
}SSTable;
//二叉链表, 次优查找树采用二叉链表的存储结构
typedef struct{
ElemType data;
struct BiTNode *lchild;
struct BiTNode *rchild;
}BiTNode, *BiTree; //由有序表R[low,...,high]及累计权值表sw(其中sw[0]==0)递归构造次优查找树T
BiTNode* SecondOptimal(ElemType R[], int sw[], int low, int high)
{
int i = low, j = ;
int min = abs(sw[high]-sw[low]);
int dw = sw[high]+sw[low-];
//选择最小的<>Pi值
for(j=low+; j<=high; ++j){
if(abs(dw-sw[j]-sw[j-])<min){
i = j;
min = abs(dw-sw[j]-sw[j-]);
}
}
#ifdef DEBUG
printf("i=%d, low=%d, high=%d\n", i, low, high);
#endif
//生成结点
BiTNode* T = (BiTNode*)malloc(sizeof(BiTNode));
T->data = R[i];
T->lchild = T->rchild = NULL;
if(i==low){
//左子树空
T->lchild = NULL;
}else{
//构造左子树
T->lchild = SecondOptimal(R, sw, low, i-);
}
if(i==high){
//右子树空
T->rchild = NULL;
}else{
//构造右子树
T->rchild = SecondOptimal(R, sw, i+, high);
}
return T;
} //按照由有序表ST中各数据元素的weight域求累计权值表sw
void FindSW(int sw[], SSTable ST)
{
int i = ;
sw[] = ;
for(i=; i<=ST.length; i++){
sw[i] = sw[i-]+ST.elem[i].weight;
}
#ifdef DEBUG
printf("SW : ");
for(i=; i<=ST.length; i++){
printf("[%d]=%-3d ", i, sw[i]);
}
printf("\n");
#endif
return ;
} //由有序表ST构造一棵次优查找树. ST的数据元素含有权域weight
BiTree CreateSOSTree(SSTable ST)
{
if(ST.length == )
return NULL;
else{
int sw[MAX_SIZE+] = {};
//按照由有序表ST中各数据元素的weight域求累计权值表sw
FindSW(sw, ST);
//由有序表ST.elem[low,...,high]及累计权值表sw(其中sw[0]==0)递归构造次优查找树并返回
return (BiTree)SecondOptimal(ST.elem, sw, , ST.length);
}
} //顺序打印有序表ST中的数据元素。
void print(SSTable SS){
printf("data: ");
int i = ;
for(i=; i<=SS.length; i++){
printf("[%d]=%c,%d ", i, SS.elem[i].key, SS.elem[i].weight);
}
printf("\n");
} int PreOrderTraverse(BiTree T); //先序遍历
int InOrderTraverse(BiTree T); //中序遍历
int PostOrderTraverse(BiTree T);//后序遍历 int main(int argc, char *argv[])
{ KeyType key;
int weight;
int i = ;
char tmp[] = {};
#ifdef DEBUG
ElemType arr[MAX_SIZE+] = {{'',},{'A',}, {'B',}, {'C',}, {'D',}, {'E',},{'F',},{'G',},{'H',},{'I',},};
i = ;
#else
ElemType arr[MAX_SIZE+];
while(){
printf("输入 关键字,权值('0,0'是结束):");
memset(tmp, , sizeof(tmp));
scanf("%s", tmp);
sscanf(tmp, "%c,%d", &key, &weight);
if(key == '' && weight ==){
break;
}else{
arr[i].key = key;
arr[i].weight = weight;
i+=;
}
}
#endif
SSTable SS;
SS.elem = arr;
SS.length = i-;
#ifdef DEBUG
print(SS);
#endif
BiTree T = CreateSOSTree(SS);
printf("先序遍历:");
PreOrderTraverse(T);
printf("\n"); printf("中序遍历:");
InOrderTraverse(T);
printf("\n"); printf("后序遍历:");
PostOrderTraverse(T);
printf("\n");
return ;
} int PreOrderTraverse(BiTree T){
if(T){
printf("%c,%d ", ((BiTNode*)T)->data.key, ((BiTNode*)T)->data.weight);
PreOrderTraverse((BiTree)T->lchild);
PreOrderTraverse((BiTree)T->rchild);
}
return ;
} int InOrderTraverse(BiTree T){
if(T){
InOrderTraverse((BiTree)T->lchild);
printf("%c,%d ", ((BiTNode*)T)->data.key, ((BiTNode*)T)->data.weight);
InOrderTraverse((BiTree)T->rchild);
}
return ;
} int PostOrderTraverse(BiTree T){
if(T){
PostOrderTraverse((BiTree)T->lchild);
PostOrderTraverse((BiTree)T->rchild);
printf("%c,%d ", ((BiTNode*)T)->data.key, ((BiTNode*)T)->data.weight);
}
return ;
}

次优查找(静态树表)

运行

查找->静态查找表->次优查找(静态树表)的更多相关文章

  1. 查找->静态查找表->折半查找(有序表)

    文字描述 以有序表表示静态查找表时,可用折半查找算法查找指定元素. 折半查找过程是以处于区间中间位置记录的关键字和给定值比较,若相等,则查找成功,若不等,则缩小范围,直至新的区间中间位置记录的关键字等 ...

  2. 查找->静态查找表->顺序查找(顺序表)

    文字描述 顺序查找的查找过程为:从表中最后一个记录开始,逐个进行记录的关键字和给定值的比较,若某个记录的关键字和给定值比较相等,则查找成功,找到所查记录:反之,若直至第一个记录,其关键字和给定值比较都 ...

  3. 查找->静态查找表->分块查找(索引顺序表)

    文字描述 分块查找又称为索引顺序查找,是顺序查找的一种改进方法.在此查找算法中,除表本身外, 还需要建立一个”索引表”.索引表中包括两项内容:关键字项(其值为该字表内的最大关键字)和指针项(指示该子表 ...

  4. Python 树表查找_千树万树梨花开,忽如一夜春风来(二叉排序树、平衡二叉树)

    什么是树表查询? 借助具有特殊性质的树数据结构进行关键字查找. 本文所涉及到的特殊结构性质的树包括: 二叉排序树. 平衡二叉树. 使用上述树结构存储数据时,因其本身对结点之间的关系以及顺序有特殊要求, ...

  5. 【ZZ】详解哈希表的查找

    详解哈希表的查找 https://mp.weixin.qq.com/s/j2j9gS62L-mmOH4p89OTKQ 详解哈希表的查找 2018-03-01 算法与数据结构 来自:静默虚空 http: ...

  6. 【知识强化】第六章 查找 6.4 散列(Hash)表

    本节课我们来学习一种新的查找方式叫做散列查找.什么是散列查找呢?在学习散列查找之前,一定要介绍一个基本概念就是散列表.那么学习散列表之前我们先来回忆一下之前所学习过的所有查找方式,那么无论是顺序查找还 ...

  7. Excel中如何在两个工作表中查找重复数据

    有时我们可能会在两种工作表中查找重复记录,当数据记录很多时,就必须通过简单的方法来实现.下面小编就与大家一起分享一下查看重复记录数据的方法,希望对大家有所帮助. 方法/步骤   为了讲解的需要,小编特 ...

  8. 在雇员表中查找第二高的工资SQL语句助记

            "在雇员表中查找第二高的工资的员工记录"SQL语句怎么写         这个查询首先查找最高工资,然后将它从列表中排除.再查找最高工资. 非常明显,第二次返回的是 ...

  9. Excel-VLOOKUP函数跨表匹配查找①

    问题场景 对表中的员工进行测评总结,从所有员工考核明细表中匹配这些参与测评的员工的得分和相关信息: 场景一 从所有员工明细表中匹配需要参与测评的员工相关信息. 建了两个sheet页,考核员工表和全员考 ...

随机推荐

  1. iOS应用开发,全局强制竖屏,部分页面允许旋转的处理

    目前大多数app都不支持横屏模式,用户不常用,开发起来也麻烦一些.但有些时候,又离不开横屏和竖屏的切换,比如查看视频.图片.文档等,这时又不得不对页面做横屏的处理.下面来教大家如何处理这种场景,方法可 ...

  2. Hadoop2.6新增用户隔离

    1.hadoop文件权限介绍 (这部分内容参考成品  https://blog.csdn.net/skywalker_only/article/details/40709447) 之前在论坛看到一个关 ...

  3. 超酷!纯CSS3烧烤动画实现教程

    今天在老外的网站上看到一款很有创意的纯CSS3动画,是模拟烧烤活动的.款动画模拟了一个烧烤架,烧烤架上的食物也都是用纯CSS3绘制而成,没有用一张图片,效果相当逼真.另外一个有意思的是,这个CSS3烧 ...

  4. eclipse java ee jsp tomcat Server文件夹给删了,怎么办?

    右键 选择属性 选择Switch location 就可以了

  5. 转:Python语言编程学习资料(电子书+视频教程)下载汇总

    开发工具: Python语言集成开发环境 Wingware WingIDE Professional v3.2.12 Python语言集成开发环境 Wingware WingIDE Professio ...

  6. android 中文api

    http://www.embeddedlinux.org.cn/androidapi/

  7. mysql 导入excel文件数据到数据库

    load data local infile 'C:/Users/Administrator/Documents/gaunai2.csv' into table newtable (c1,c2) fi ...

  8. 使用 ssh -R 穿透局域网访问内部服务器主机,反向代理 无人值守化

    一.搭建SSH方向代理 准备: 局域网主机(虚拟主机): 192.168.6.233   CentOS 6.7 阿里云服务器:120.25.68.60   CentOS 6.7 1. 阿里云服务器12 ...

  9. VMware Workstation11安装Mac OS X 10.10虚拟机

    原文:http://jingyan.baidu.com/article/3f16e003eac66e2591c103e0.html 优化:http://www.cnblogs.com/yipu/p/4 ...

  10. Linux-C实现GPRS模块发送短信

    “GSM模块,是将GSM射频芯片.基带处理芯片.存储器.功放器件等集成在一块线路板上,具有独立的操作系统.GSM射频处理.基带处理并提供标准接口的功能模块.GSM模块根据其提供的数据传输速率又可以分为 ...