看数据结构写代码(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;
}
运行截图:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值