zoukankan      html  css  js  c++  java
  • 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;
    }

         程序运行结果如图:



  • 相关阅读:
    FluentValidation 验证框架笔记1
    AutoMapper 笔记1
    MediatR框架笔记1
    vscode调试python时提示无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称的解决方法
    Selenium使用自带浏览器自动化
    Selenium启动Chrome插件(Chrome Extensions)
    Gitee,Github 图片转直链
    CentOS 7.3 修改root密码 passwd: Authentication token manipulation error
    阿里云服务器 被入侵植入dhpcd导致cpu飙升100%问题
    Github 切换分支
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3141008.html
Copyright © 2011-2022 走看看