文字描算

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

  如果只考虑查找成功的情况,则使查找性能达最佳的判定树是其带权内路径长度之和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. ffmpeg主体架构分析

    [时间:2016-07] [状态:Open] [关键词:ffmpeg,libavcodec,libavformat] FFmpeg接触几年了,用的比较多的是libavcodec和libavformat ...

  2. Android开发(十七)——关闭中间activity

    参考: http://java--hhf.iteye.com/blog/1826880

  3. apache kylin2.10在原生hadoop集群上安装

    Install Kylin Download latest Kylin binaries at http://kylin.apache.org/download Export KYLIN_HOME p ...

  4. sql server 获取动态sql输出结果

    不带输出结果 我们一般会这样写 例子:一个输出6位递增号码结果 ALTER proc GetCode ), ) as declare @sqlstring nvarchar(max) set @sql ...

  5. Pwnium CTF2014 – MatterOfCombination writeup

    这道题是虽然只有75分,但是做出来的队伍却很少,我们队伍也没有做出来,这次是看到了0xAWES0ME 的解题思路后才有了这篇文章.原文地址可以点击看这里,英文的. 题目就是一张图片: 在网上可以找到这 ...

  6. java二叉树字典查询(qq 928900200)

    This assignment will help you practice and understand better the Binary Tree and Binary Search Tree ...

  7. [工具类] 读取解析json文件

    读取json文件并转换为字符串 /** * 通过本地文件访问json并读取 * * @param path:json文件路径 * @return:json文件的内容 */ public static ...

  8. ORA-00001: unique constraint (...) violated并不一定是数据冲突

    原文链接:http://blog.163.com/jet_it_life/blog/static/205097083201301410303931/ 收到一位测试人员RAISE的JIRA,说在某张表上 ...

  9. [Object Tracking] Overview of Object Tracking

    From: 目标跟踪方法的发展概述 From: 目标跟踪领域进展报告 通用目标的跟踪 经典目标跟踪方法 2010 年以前,目标跟踪领域大部分采用一些经典的跟踪方法,比如 Meanshift.Parti ...

  10. [Artoolkit] Framework Analysis of nftSimple

    What is nftSimple? Loads NFT dataset names from a configuration file. The example uses the “Pinball. ...