自己写的小算法,大佬帮忙找找BUG
  • 板块学术版
  • 楼主五年长久
  • 当前回复12
  • 已保存回复12
  • 发布时间2021/8/14 14:56
  • 上次更新2023/11/4 10:42:00
查看原帖
自己写的小算法,大佬帮忙找找BUG
444078
五年长久楼主2021/8/14 14:56

自己写的产生随机数组的算法,注释详细,这里不多说了,请大佬帮我找找有没有BUG,或者有没有注释写的不对的地方,或者有没有优化。 另外,这是我自己想到的,如果有人知道有人已经发明了这种算法,也请指出来。

//exam_KeyUpsetAlgorithm
/*
*算法理论:
*	对于一棵无根树,令任何一个结点为根都会行程一棵全新的、随机的树。重复此过程,令每一棵长度>1的子树达到随
*	机,(不一定是二叉树,但最大度数一定在[2,树的结点数/2]的区间内)返回回来之后,形成的树是一个随机的,则
*	该树产生的生成数组也是一个随机的。 	
*伪代码:
*	对于每次生成根结点:
*		root<-(-INF)
*		如果root在树中出现过或者非法或者root还未生成 
*			root<-rand(1,n) //可以优化为rand(l,r)
*		num<-rand(2,n/2) //n表示树的结点数 
*		a[++cnt]=g[root] //a表示生成数组,cnt表示当前点的位置,g表示第i个位置表示的值是什么 
*		循环num次,继续生成num个子树
*时间复杂度估计:
*	耗时部分:
*		1.产生root,最坏为n
*		2.产生子树,最坏为n/2
*		3.枚举每个生成的根结点,时间为n
*	综上考虑:	保守估计:	O(2*n^2+n^2)
*				大致为:	O(n^2)
*产生随机数组数量估计:
*	对于每一个点,都可能产生n+1种选择,但是由于是一个整体,所以是一个近似(n+1)!的数量 
*/
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <map>
#define INF (0x3f3f3f3f)
#define MAXN 1005
using namespace std;
typedef int t1;
int n,m,cnt;
map<t1,int> book;
int a[MAXN],g[MAXN];
void KeyUpsetAlgorithm(){
	if(n==0)return ;
	int root=-INF;
	while(root==-INF||!book[g[root]]){
		root=rand()%m+1;
	}
	a[++cnt]=g[root];
	book[g[root]]--;
	n--;if(n==0){return ;}
	int num=rand()%n+1;
//	cout<<"将根结点定为"<<root<<",生成"<<num<<"个子树,现在"<<g[root]<<"还剩"<<book[root]<<"个\n"; 
	for(int i=1;i<=num&&n!=0;i++){
		KeyUpsetAlgorithm();
	}
}
int main(){
	srand(time(NULL));//令随机数按照时间戳生成
	while(cin>>g[++n])book[g[n]]++;
	n--;
	m=n;
	KeyUpsetAlgorithm();
	for(int i=1;i<=cnt;i++){
		cout<<a[i]<<" ";
	} 
	return 0;
}
2021/8/14 14:56
加载中...