一、目的
1.熟悉算法设计的基本思想
2.掌握计数排序(count sort)的方法
二、内容与设计思想
有一个公司想开发一个关于花卉的百科全书,用户只要输入花卉的名称,就能够输出花卉的详细信息。花卉包括:牡丹、芍药、茶花、菊花、梅花、兰花、月季、杜鹃花、郁金香、茉莉花、海棠、荷花、栀子花、莲花、百合、康乃馨、玫瑰、格桑花。公司也在试运行阶段发现这些花的访问频率不一,有些花经常性被访问,有些被访问的次数就少很多了。这18种花中,第1种的访问频率是6,第2-3种的访问频率是5,第4-6种的访问频率是4,第7-10种的访问频率是3,第11-15种的访问频率是2,第16-18种的访问频率是1。
这个公司想提升花卉检索效率,所以对比了三种方法。
1、构建优化的二叉搜索树(optimal BST),进行搜索。
// 0.112*1 0.094*2 0.075*3 0.057*4 0.038*5 0.019*3
#include<bits/stdc++.h>
using namespace std;
#define N 18
int main()
{
int i,j,l,r;
double t;
double p[19]={0,0.112,0.094,0.094,0.075,0.075,0.075,0.057,0.057,0.057,0.057,0.038,0.038,0.038,0.038,0.038,0.019,0.019,0.019};
double q[19]={0};
double e[N+2][N+1]={0};
double w[N+2][N+1]={0};
int root[N+1][N+1]={0};
for (i=1;i<=N+1;i++)
{
e[i][i-1]=q[i-1];
w[i][i-1]=q[i-1];
}
for (l=1;l<=N;l++)
{
for (i=1;i<=N-l+1;i++)
{
j=i+l-1;
e[i][j]=1000;
w[i][j]=w[i][j-1]+p[j]+q[j];
for (r=i;r<=j;r++)
{
t=e[i][r-1]+e[r+1][j]+w[i][j];
if (t<e[i][j])
{
e[i][j]=t;
root[i][j]=r;
}
}
}
}
cout<<endl;
for (i=1;i<=N+1;i++)
{
for (j=0;j<=N;j++)
{
cout<<e[i][j]<<"\t";
}
cout<<endl;
}
cout<<endl;
for (i=1;i<=N+1;i++)
{
for (j=0;j<=N;j++)
{
cout<<w[i][j]<<"\t";
}
cout<<endl;
}
cout<<endl;
for (i=1;i<=N;i++)
{
for (j=1;j<=N;j++)
{
cout<<root[i][j]<<"\t";
}
cout<<endl;
}
return 0;
}
2、将这些花卉按照访问频度从高到低放在一个数组中,并顺序访问来检索
#include<bits/stdc++.h>
using namespace std;
int Num=1000;
int main()
{
int arr[18]={6,5,5,4,4,4,3,3,3,3,2,2,2,2,2,1,1,1};
clock_t startTime,endTime;
startTime = clock();
for (int k=1;k<=Num;k++)
{
for (int i=0;i<18;i++)
{
cout<<arr[i]<<" ";
}
}
cout<<endl;
endTime = clock();
cout << "The run time is:" <<(double)(1000*(endTime - startTime) / CLOCKS_PER_SEC) << "ms" << endl;
return 0;
}
3、构建哈希表来存储这些数据,并基于哈希表来检索数据。
#include<bits/stdc++.h>
using namespace std;
#define MAXHSIZE 100000001
#define NULLKEY -32768
int HASHSIZE;
int Num=1000;
typedef struct
{
int *elem;
int count;
} HashTable;
int m = 0;
int Init(HashTable *H)
{
int i;
m = HASHSIZE;
H->elem = (int *)malloc(m * sizeof(int));
H->count = m;
for (i = 0; i<m; i++)
{
H->elem[i] = NULLKEY;
}
return 1;
}
int Hash(int k)
{
return k % m;
}
void Insert(HashTable *H, int k)
{
int addr = Hash(k);
while (H->elem[addr] != NULLKEY)
{
addr = (addr+1) % m;
}
H->elem[addr] = k;
}
int Search(HashTable *H, int k)
{
int addr = Hash(k);
while (H->elem[addr] != k)
{
addr = (addr+1) % m;
if (H->elem[addr] == NULLKEY || addr == Hash(k))
return -1;
}
return addr;
}
void Result(HashTable *H)
{
int i;
for (i = 0; i<H->count; i++)
{
cout<< H->elem[i]<<" ";
}
cout<<endl;
}
int main()
{
int i, j, addr;
HashTable H;
// cin>>HASHSIZE;
int arr[18]={6,5,5,4,4,4,3,3,3,3,2,2,2,2,2,1,1,1};
HASHSIZE=18;
clock_t startTime,endTime;
startTime = clock();
for (int k=1;k<=Num;k++)
{
Init(&H);
for (i = 0; i<HASHSIZE; i++)
{
Insert(&H, arr[i]);
}
Result(&H);
}
endTime = clock();
cout << "The run time is:" <<(double)(1000*(endTime - startTime) / CLOCKS_PER_SEC) << "ms" << endl;
return 0;
}
请实现这三种方法,并且通过实验来比较这三种方法的优劣。