问题描述
用两个数组来表示所给的含有n个元素的有序集S。用value[0:n]存储有序集中的元素,link[0:n]存储有序集中元素在数组value中位置的指针(实际上使用数组模拟链表)。link[0]指向有序集中的第一个元素,集value[link[0]]是集合中的最小元素。一般地,如果value[i]是所给有序集S中的第k个元素,则value[link[i]]是S中第k+1个元素。S中元素的有序性表现为,对于任意1<=i<=n有value[i]<=value[link[i]]。对于集合S中的最大元素value[k]有,link[k]=0且value[0]是一个大数。
例:有序集S={1,2,3,5,8,13,21}的一种表现方式如图所示:
搜索思想
对于有序链表,可采用顺序搜索的方式在所给的有序集S中搜索值为x的元素。如果有序集S中含有n个元素,则在最坏的情况下,顺序搜索算法所需的计算时间为O(n)。利用数组下标的索引性质,可以设计一个随机化搜索算法,一改进算法的搜索时间复杂性。算法的基本思想是,随机抽取数组元素若干次,从较接近搜索元素x的位置开始做顺序搜索。如果随机搜索数组元素k次,则其后顺序搜索所需的平均比较次数为O(n/k+1)。因此,如果去k=|sqrt(n)|,则算法所需的平均计算时间为(Osqrt(n))。
随机化思想下的有序表实现具体代码如下:
1、RandomNumber.h
#include"time.h"
//随机数类
const unsigned long maxshort = 65536L;
const unsigned long multiplier = 1194211693L;
const unsigned long adder = 12345L;
class RandomNumber
{
private:
//当前种子
unsigned long randSeed;
public:
RandomNumber(unsigned long s = 0);//构造函数,默认值0表示由系统自动产生种子
unsigned short Random(unsigned long n);//产生0:n-1之间的随机整数
double fRandom(void);//产生[0,1)之间的随机实数
};
RandomNumber::RandomNumber(unsigned long s)//产生种子
{
if(s == 0)
{
randSeed = time(0);//用系统时间产生种子
}
else
{
randSeed = s;//由用户提供种子
}
}
unsigned short RandomNumber::Random(unsigned long n)//产生0:n-1之间的随机整数
{
randSeed = multiplier * randSeed + adder;//线性同余式
return (unsigned short)((randSeed>>16)%n);
}
double RandomNumber::fRandom(void)//产生[0,1)之间的随机实数
{
return Random(maxshort)/double(maxshort);
}
2、7d3d2.cpp
//随机化算法搜素有序表
#include "stdafx.h"
#include "RandomNumber.h"
#include "math.h"
#include <iostream>
using namespace std;
template<class Type>
class OrderedList
{
friend int main();
public:
OrderedList(Type Small,Type Large,int MaxL);
~OrderedList();
bool Search(Type x,int& index); //搜索指定元素
int SearchLast(void); //搜索最大元素
void Insert(Type k); //插入指定元素
void Delete(Type k); //删除指定元素
void Output(); //输出集合中元素
private:
int n; //当前集合中元素的个数
int MaxLength; //集合中最大元素的个数
Type *value; //存储集合中元素的数组
int *link; //指针数组
RandomNumber rnd; //随机数产生器
Type Small; //集合中元素的下界
Type TailKey; //集合中元素的上界
};
//构造函数
template<class Type>
OrderedList<Type>::OrderedList(Type small,Type Large,int MaxL)
{
MaxLength = MaxL;
value = new Type[MaxLength+1];
link = new int[MaxLength+1];
TailKey = Large;
n = 0;
link[0] = 0;
value[0] = TailKey;
Small = small;
}
//析构函数
template<class Type>
OrderedList<Type>::~OrderedList()
{
delete value;
delete link;
}
//搜索集合中指定元素k
template<class Type>
bool OrderedList<Type>::Search(Type x,int& index)
{
index = 0;
Type max = Small;
int m = floor(sqrt(double(n)));//随机抽取数组元素次数
for(int i=1; i<=m; i++)
{
int j = rnd.Random(n)+1;//随机产生数组元素位置
Type y = value[j];
if((max<y)&& (y<x))
{
max = y;
index = j;
}
}
//顺序搜索
while(value[link[index]]<x)
{
index = link[index];
}
return (value[link[index]] == x);
}
//插入指定元素
template<class Type>
void OrderedList<Type>::Insert(Type k)
{
if((n == MaxLength)||(k>=TailKey))
{
return;
}
int index;
if(!Search(k,index))
{
value[++n] = k;
link[n] = link[index];
link[index] = n;
}
}
//搜索集合中最大元素
template<class Type>
int OrderedList<Type>::SearchLast(void)
{
int index = 0;
Type x = value[n];
Type max = Small;
int m = floor(sqrt(double(n)));//随机抽取数组元素次数
for(int i=1; i<=m; i++)
{
int j = rnd.Random(n)+1;//随机产生数组元素位置
Type y = value[j];
if((max<y)&&(y<x))
{
max = y;
index = j;
}
}
//顺序搜索
while(link[index]!=n)
{
index = link[index];
}
return index;
}
//删除集合中指定元素
template<class Type>
void OrderedList<Type>::Delete(Type k)
{
if((n==0)&&(k>=TailKey))
{
return;
}
int index;
if(Search(k,index))
{
int p = link[index];
if(p == n)
{
link[index] = link[p];
}
else
{
if(link[p]!=n)
{
int q = SearchLast();
link[q] = p;
link[index] = link[p];
}
value[p] = value[n];//删除元素由最大元素来填补
link[p] = link[n];
}
n--;
}
}
//输出集合中所有元素
template<class Type>
void OrderedList<Type>::Output()
{
int index = 0,i = 0;
while(i<n)
{
index = link[index];
cout<<value[index]<<" ";
i++;
}
cout<<endl;
cout<<"value:";
for(i=0; i<=n; i++)
{
cout.width(4);
cout<<value[i];
}
cout<<endl;
cout<<"link:";
for(i=0; i<=n; i++)
{
cout.width(4);
cout<<link[i];
}
cout<<endl;
}
int main()
{
static RandomNumber rnd;
OrderedList<int> *ol = new OrderedList<int>(0,100,100);
//创建
cout<<"=========创建==========="<<endl;
while(ol->n<10)
{
int e = rnd.Random(99);
ol->Insert(e);
}
ol->Output();
cout<<endl;
//搜索
cout<<"=========搜索==========="<<endl;
int index;
cout<<"搜索有序表value数组中第5个元素如下:"<<endl;
cout<<"value[5]="<<ol->value[5]<<endl;
ol->Search(ol->value[5],index);
cout<<"位置搜索结果为:"<<ol->link[index]<<endl;
cout<<endl;
//删除
cout<<"=========删除==========="<<endl;
cout<<"删除有序表value数组中第5个元素如下:"<<endl;
cout<<"value[5]="<<ol->value[5]<<endl;
ol->Delete(ol->value[5]);
ol->Output();
delete ol;
return 0;
}
程序运行结果如图: