0045算法笔记——【随机化算法】舍伍德随机化思想搜索有序表

     问题描述

     用两个数组来表示所给的含有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;
}
     程序运行结果如图:

0045算法笔记——【随机化算法】舍伍德随机化思想搜索有序表_第1张图片

你可能感兴趣的:(舍伍德算法,算法笔记,有序表,随机化搜索)