看数据结构写代码(54)次优查找树

查找顺序表时,若 每个元素的概率 都相等 用 二分查找 效率 最高。但是 如果 概率 不相等时,(SOST)静态最优查找表 效率 要高于 二分查找。静态最优查找表 是 使得 从 根 到 每个节点的路径 长度 和 权值 乘积 之和 最小。

书上说的 静态最优 查找树的创建 时间 复杂度 较高,所以 用 次优 查找树(NOST) 代替。

下面 上代码:

// Nost.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <cstdlib>
#include <cmath>

typedef struct Node{//次优查找树.
	char data;
	Node * leftChild;
	Node * rightChild;
}*NosTree;

void getAllSum(int * sumArray,int * wArray,int len){
	sumArray[0] = wArray[0];
	for (int i = 1; i < len; i++){
		sumArray[i] = sumArray[i-1] + wArray[i];
	}
}

//vArray: 值数组,sumArray,概率和数组
void secondOptimal(NosTree * tree,char * vArray,int * sumArray,int low,int high){
	int min = (int)fabs((float)(sumArray[high] - sumArray[low]));
	int k = low;
	int dw = sumArray[high] + sumArray[low-1];
	for (int i = low+1; i <= high; i++){
		int newMin = fabs(float(sumArray[high]-sumArray[i]-sumArray[i-1]));
		if (newMin < min){
			min = newMin;
			k = i;
		}
	}
	NosTree p = *tree = (NosTree)malloc(sizeof(Node));
	p->data = vArray[k];
	if (k == low){
		p->leftChild = NULL;
	}
	else{
		secondOptimal(&p->leftChild,vArray,sumArray,low,k-1);
	}
	if (k == high){
		p->rightChild = NULL;
	}
	else{
		secondOptimal(&p->rightChild,vArray,sumArray,k+1,high);
	}
}

int find(NosTree t,char key){
	printf("--------查找经过了:");
	while (t != NULL){
		printf("%c\t",t->data);
		if (t->data == key){
			return 1;
		}
		else if(t->data > key){
			t = t->leftChild;
		}
		else{
			t = t->rightChild;
		}
	}
	return 0;
}

void preOrderTraver(NosTree t){
	if (t != NULL){
		printf("%c\t",t->data);
		preOrderTraver(t->leftChild);
		preOrderTraver(t->rightChild);
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	char *array= "abcdefghi";
	int weitht[9] = {1,1,2,5,3,4,4,3,5};
	int sum[9];
	getAllSum(sum,weitht,9);
	NosTree tree = NULL;
	secondOptimal(&tree,array,sum,0,8);
	printf("-------------次优查找树先序遍历--------------\n");
	preOrderTraver(tree);
	printf("\n-------------查找h--------------\n");
	int f = find(tree,'h');
	return 0;
}

运行截图:

时间: 2024-09-30 19:50:24

看数据结构写代码(54)次优查找树的相关文章

看数据结构写代码(33) 树与回溯法(一) 子集树

回溯法 是 一种 在 穷举 中,裁剪 不满足 条件 的 分支,已达到 提高 效率的 方法.其基本原型 是 树的 先序遍历,从 树根 到 树叶的路径 是 问题的 一个 解. 回溯法的基本框架 =  确定 解空间 + 深度优先遍历 + 裁剪函数 + 确定结果函数 其中 解空间,分为 子集树 和 排序树. 具体 概念 详解:参考 点击打开链接  和 点击打开链接 递归算法通用 模板如下: 回溯法对解空间作深度优先搜索,因此,在一般情况下用递归方法实现回溯法. // 针对N叉树的递归回溯方法 void

看数据结构写代码(34) 树与回溯法(二)排序树(8皇后问题)

套用回溯 公式程序: void backtrack (int t) { if (t > n) { // 到达叶子结点,将结果输出 output (x); } else { // 遍历结点t的所有子结点 for (int i = f(n,t); i <= g(n,t); i ++ ) { x[t] = h[i]; // 如果不满足剪枝条件,则继续遍历 if (constraint (t) && bound (t)) backtrack (t + 1); } } } 写出 8皇后问

看数据结构写代码(57) AVL树的删除

上一节 已经说了 AVL树的插入 操作,可是 只有 插入,没有删除,怎么能叫 动态 查找表呢. 呵呵,博主 赶紧 去 研究了一番.下面 是成果: AVL树的删除 大致 分为 两大块: 1. 查找节点 并 删除 2. 保持 删除 后 平衡因子的 影响 1. 首先 找到 这个 节点,如果 节点 不存在,直接 退出 函数 if (*tree == NULL){//没找到 return false; } 2.如果 存在,分为 四种情况:(根 二叉 排序树的 删除 类似) 1.节点 为 叶子 节点,直接

看数据结构写代码(59) 键树的双链表示法

杂谈; 打败自己的 往往不是敌人,而是自己.坚持不易,且行且珍惜. 键树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高 键树的根节点不包含字符,除根节点外的非叶子节点都只包含一个字符,叶子节点存储具体信息.: 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串:

看数据结构写代码(32) 赫夫曼树编码以及译码

杂谈:最近有点慵懒,不好不好.好几天都没写代码,原本准备上星期完结 树 这一章节的.现在 又耽误了.哎.要抓紧时间啊. 下面直接上代码: 可以到我的网盘下载源代码,或者 直接拷贝下面的源代码 运行 网盘地址:点击打开链接 // HuffmanTree.cpp : 定义控制台应用程序的入口点. //哈弗曼编码,译码 #include "stdafx.h" #include <stdlib.h> #include <cstring> enum E_State { E

看数据结构写代码(53) 静态查找表(线性查找,二分查找,斐波那契查找,插值查找)

查找定义:根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录). 查找表分类:静态查找表和动态查找表. 静态查找表:只查找,而不进行插入,删除. 动态查找表:在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素. 静态表的 查找 大致 四种 算法: 线性查找,二分查找,斐波那契查找和插值查找. 其中 在线性查找之前,对表 无要求.对于 其余三种 需要 在查找之前 排序.插值查找 除了 需要 排序,还需要 均匀分布. 下面 给出代码: 线性查

看数据结构写代码(58) B-树

B-树 一种 自平衡的 多路 查找树.它在文件系统里很有用. 一个m阶的B-树,要么是空树,要么是满足这些特性的树.. 1.树 最多 有 m个分支. 2.树的根 最少 两个子树. 3. 树的非终端叶子节点 最少  m/2 向上 取整   个 子树. 4.所有叶子节点 都在 一层. 它的节点 结构:  (N,P0,K1,P1,K2,p2......Kn,Pn) 其中 N 是 节点的 关键字个数,p0~pn 是 指向子树的指针,K1~Kn是关键字 #define M 3 //B树的阶数.. type

看数据结构写代码(55) 二叉排序树

二叉排序树 是一种 动态 查找树,它的 创建 是在 查找中 生成的. 当 查找 失败时,它将 数 插入到 合适的 位置中去. 二叉查找树的 左子树上的值 父亲的 值 小,而 右子树上的值 总是 比 父节点 大.这样 查找 类似与 二分 查找,其 最多 查找 的 次数 等于 树的 深度. 下面的代码 主要 是 两方面:插入 节点 和 删除 节点. 下面 给出 代码, 欢迎 指出 代码 不足: // BinarySortTree.cpp : 定义控制台应用程序的入口点. // #include "s

看数据结构写代码(66) 败者树

计算机的 内存 是 有限的,无法 存入 庞大的数据.当 遇到 大数据需要排序时,我们 需要 将 这些 数据 分段 从 硬盘里 读到 内存中,排好序,再 写入到 硬盘中,这些段 叫做 归并段.最后将 这些 分段 合并 成 一个 最终  完整 有序的 数据. 这里 操作的 时间 =  内部 排序 时间 +  外存读写时间 + 内部归并所需时间. 其中 外存 读写时间 最耗时,外存读写时间 = 读写次数 * 读写数据的时间 ,读写 数据的时间 因 设备 性能 而 影响,我们 无法控制,我们 只能 控制