关于树的那点事。

突发奇想的想写一些关于树的用法,以后把经常用到的或者觉得重要的用法都给整理下来,好复习用。

因为用得比较多的是二叉树,所以先说一些二叉树的性质:
性质1:二叉树第i层上的结点数目最多为2i-1(i >= 1);
性质2:深度为k的二叉树至多有2k-1个结点(k >= 1);
性质3:包含n个结点的二叉树的高度(k)至少为(log2n)+1(k >= 1);
性质4:在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0 = n2 +1。

二叉树的遍历:
前序遍历:根——左——右
中序遍历:左——根——右
后序遍历:左——右——根

满二叉树、完全二叉树
一、满二叉树
定义:高度为k(k >= 1),且节点个数为2k-1的二叉树,称为满二叉树。
特点:最高层全为叶子节点。

二、完全二叉树
定义:若设二叉树的深度为k,除第k层外,其它各层 (1~k-1) 的结点数都达到最大个数,第k层所有的结点都连续集中在最左边,这就是完全二叉树。
特点:完全二叉树中节点的度为1的节点个数为1或0。

用法:
①根据边(无向图)的关系来建立二叉树(将边的权值问题转换为节点的权值问题):
edgeweight[x][y] 保存节点x、y之间权值 tree[x][0]/[1]表示根节点x的左孩子/右孩子结点 pointweight[p]表示节点p的权值
build(root, c, lor):建立根节点root与孩子节点c的关系,lor == 0表示左孩子, lor == 1表示右孩子
在建立结点关系的时候,可以将root与c之间边的权值保存到子节点c中,这样就实现了将边的权值问题转换为节点的权值问题了
make_tree(root):以root为根节点建立二叉树,遍历edgeweight[root][k(0~end)]
如果遇到root与k有边的关系,则让k成为root的孩子节点(第一次为左孩子,第二次为右孩子(根据题目需求来))
需要注意的是在用build建立关系时,需要在建立完成后让edgeweight[root][k] 与 edgeweight[k][root] 的权值无效化,防止形成环

#define ineffective -1

vector<vector<int> > edgeweight, tree;
vector<int> pointweight;

void make_tree(int root);

void build(int root, int c, int lor) {
	tree[root][lor] = c;
	pointweight[c] = edgeweight[root][c];  //边权值转换为点权值
	//使边的权值无效化,防止再次建立关系
	edgeweight[root][c] = edgeweight[c][root] = ineffective; 
	make_tree(c); //递归建树
}

void make_tree(int root) {
	int lor = 0;
	for (size_t i = 0; i < edgeweight[root].size(); ++i) {
		if (edgeweight[root][i] != ineffective) {
			build(root, i, lor++);
			if (lor > 1) break;
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值