强迫症的随机二叉树

分享一个生成随机二叉树的小想法

PS:写这篇帖的人患了强迫癌,症状极其严重。

最近学习数据结构写了一些二叉树的算法,但偶尔调试的时候想整一棵随机二叉树来验证,自己建总是觉得随机性不高,所以抱着研究的心态写一个生成随机二叉树的代码,跟大家分享一个想法,有不足的地方,但希望可以帮到一些有需要的朋友。
关于二叉树的概念,网上很多大神的分析都很到位,而且还有动画大神直接图形化的超级带感,这里就不多说了。由于后面要用到节点位置的值,所以这里简单讲一下二叉树位置的一些表示方法:
满和非满位置
对于左边的满二叉树而言,根节点位置是1,那么它的左右节点位置就分别是2和3,这样,相对于满二叉树,如果说有效位置为1、2、3、5、7就可以画出右边的非满二叉树,位置4、6为空。不难看出,位置为n的节点的左右节点位置分别为2n和2n+1,此时我们可以构造这样一个结构体来表示树的节点:

struct tree{
	int pos;		//储存节点位置
	tree *left;		//左指针
	tree *right;	//右指针
};

接下来就要把节点接成一棵树了,随机生成树的方法有很多,我也看过有把一个数组转化成随机数的程序,但是本人强迫比较严重,对数组的长度限制非常不高兴,所以这里用单链表来转化。
节点链表如上图,用节点的同侧指针把节点连成一串,另一侧指空,可以生成自定义节点个数的单链表,如下函数:

//给定节点个数生成左连接链表,返回头指针
tree *create_list(){
	int n; tree *head,*tail;
re:	cout<<"输入你打算创建的节点个数:";
	cin>>n;
	if(!n){
		cout<<"哎!别输入0 啊!"<<endl;
		goto re;
	}
    head = new tree;
	tail = head;
	for(int i=0;i<n-1;i++){
		tail->left = new tree;
		tail = tail->left;
	}tail->left=NULL;		
	return head;
}

可以把链表想象成一串珠子,我们现在生成了有n个珠子的一个串,要变成树,只要每次把珠子接到根节点的随机侧,然后把多余的珠子剪下来

//拆链表接树,返回树根指针
tree *create_tree(tree *head){
	tree *trunk;
	trunk = head;
	head = head->left;
	trunk->pos=1;
	trunk->left=NULL;
	trunk->right=NULL;
	cout<<"造树成功!"<<endl<<"有效位置为:1 ";
	while(head!=NULL)head=node_cnt(trunk,head);
	cout<<endl;
	return trunk;
}

//node_cnt接收链表头节点随机接入二叉树中并显示位置
tree *node_cnt(tree *node,tree* head){
	switch(rand()%2){		//随机选择方向
	case 0:{
			  if(node->left == NULL){
				  node->left = head;
				  node->left->pos = 2*node->pos;
				  cout<<node->left->pos<<'\0';
				  head = head->left;
				  node->left->left = NULL;
				  node->left->right = NULL;
			  }else head=node_cnt(node->left,head);
			  return head;
		   }
	case 1:{	
			  if(node->right == NULL){
				  node->right = head;
				  node->right->pos = 1+2*node->pos;
				  cout<<node->right->pos<<'\0';
				  head = head->left;
				  node->right->left = NULL;
				  node->right->right = NULL;
			  }else head=node_cnt(node->right,head);
			  return head;
		   }
	}
}

再通过主函数调用:

void main(){
	tree *root;
	srand((unsigned)time(NULL));	//用系统时间做随机种
	root = create_tree(create_list());
	}

运行结果
运行结果总体感觉:万物皆可串珠子。

代码存在不足的地方,欢迎大家指点学习,交流方法。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值