当一列数中的查找概率各不相等的时候就需要利用次优排序来减少查找的次数,而不是利用折半查找。所以这个方法的一个前提也是说必须是有序序列,但是这个序列的每个值得查找概率不同。
代码:
代码是拷贝的别人的。。。。。。。所以有些地方还不是很理解。。
---------------------------------------------------------------------------------------------本文还需继续研究!!!!!!!!-------------------------------------------
#include <iostream>
#include <math.h>
using namespace std;
typedef struct BiTNode
{
int data;
int LTag,RTag; //标志位,=1表示lchild或rchild指示结点的左右孩子,=0表示指示结点的前驱后继
struct BiTNode *lchild,*rchild;
}BiTNode, *BiTree;
typedef BiTree SOSTree; //次优查找树用二茬链表存储结构
typedef struct SSTable{
double weight[20];
int elem[20];
int length;
}SSTable;
void SecondOptimal(BiTree &T, int R[], double sw[], int low, int high);
void CreateSOSTree(SOSTree &T, SSTable ST);
void FindSW(double sw[], SSTable ST);
void SecondOptimal(BiTree &T, int R[], double sw[], int low, int high)
{ //由有序表R[low..high],以及其累计权值表sw(sw[0]=0)递归构造次优查找树T
int i,j;
i = low;
double min = fabs(sw[high]-sw[low]);
double dw = sw[high] + sw[low-1];
for(j=low+1; j<=high; ++j)
if(fabs(dw-sw[j]-sw[j-1]) < min)
{
i=j;
min = fabs(dw-sw[j]-sw[j-1]);
};
T = (BiTree)malloc(sizeof(BiTNode));
T->data = R[i]; //生成结点
cout<<T->data<<endl;
T->lchild = NULL;
T->rchild = NULL;
if(i == low)
T->lchild = NULL; //左子树空
else
SecondOptimal(T->lchild, R, sw, low, i-1); //构造左子树
if(i == high)
T->rchild = NULL; //右子树空
else
SecondOptimal(T->rchild, R, sw, i+1, high); //构造右子树
}
void CreateSOSTree(SOSTree &T, SSTable ST)
{ //由有序表ST,构造一棵次优查找树T,ST的数据元素含义权域weight
double sw[20];
if(ST.length == 0)
T = NULL;
else
{
FindSW(sw, ST); //按有序表ST计算各数据元素的weight域累计权值表sw
SecondOptimal(T, ST.elem, sw, 1, ST.length);
}
}
void FindSW(double sw[], SSTable ST)
{ //按有序表ST计算各数据元素的weight域累计权值表sw
int i,j;
sw[0] = 0;
for(i=1; i<=ST.length; ++i)
sw[i] = sw[0] + ST.elem[i];
}
void PreOrderTraverse(BiTree T)
{
if(T){
/*以先序方式遍历,若要以中序或后序遍历,只需改变以下三句顺序*/
cout<<T->data<<endl;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
int main()
{
SSTable ST;
double a[10] = { 0, 1, 1, 2, 5, 3, 4, 4, 3, 5 };
int i = 0;
int j = 0;
printf("请输入权重序列!\n");
while (getchar() != '\n')
{
scanf("%d", &ST.weight[i]);
i++;
}
printf("请输入数值序列!\n");
while (getchar() != '\n')
{
scanf("%d", &ST.elem[j]);
j++;
}
ST.length = 9;
SOSTree T;
CreateSOSTree(T, ST);
cout << "先根遍历:" << endl;
PreOrderTraverse(T);
return 0;
}