必知C++算法之二叉树基本操作

测试用树

	TreeNode* root = new TreeNode(1);
	TreeNode* left = new TreeNode(2);
	TreeNode* right = new TreeNode(3);
	TreeNode* left2 = new TreeNode(4);
	TreeNode* right2 = new TreeNode(5);
	TreeNode* left3 = new TreeNode(6);
	TreeNode* right3 = new TreeNode(7);

	root->left = left;
	root->right = right;
	left->left = left2;
	left->right = right2;
	right->left = left3;
	right->right = right3;

二叉树的遍历(递归版)

//递归版后序遍历
void BinarytreeTraversal(TreeNode* root) {
	if (root == nullptr)
		return;
	BinarytreeTraversal(root->left);
	BinarytreeTraversal(root->right);
	cout << root->val << " ";//改变根节点的位置来实现前中后遍历即可
	
}

二叉树的前序遍历(非递归单栈式)

void PreorderTraversal(TreeNode* root) {
	if (root == nullptr)
		return;
	stack<TreeNode*> s1;
	TreeNode* cur;
	s1.push(root);
	while (!s1.empty()) {
		cur = s1.top();
		s1.pop();
		cout << cur->val << " ";
		if (cur->right)
			s1.push(cur->right);
		if (cur->left)
			s1.push(cur->left);
	}
}

二叉树的中序遍历(非递归单栈式)

void InorderTraversal(TreeNode* root) {
	if (root == nullptr)
		return;
	stack<TreeNode*> s1;
	TreeNode* cur = root;
	TreeNode* node;
	while ((!cur) || (!s1.empty())) {
		if (cur) {
			s1.push(cur);
			cur = cur->left;
		}
		else if (!cur) {
			node = s1.top();
			s1.pop();
			cout << node->val << " ";
			cur = node->right;
		}
	}
}

二叉树的后序遍历

方法一:(非递归双栈式)
void PostorderTraversal(TreeNode* root) {
	stack<TreeNode*> s1;
	stack<TreeNode*> s2;
	TreeNode* cur = nullptr;
	if (root == nullptr)
		return;
	s1.push(root);
	while (!s1.empty()) {
		cur = s1.top();
		s1.pop();
		s2.push(cur);
		if(cur->left)
		s1.push(cur->left);
		if(cur->right)
		s1.push(cur->right);
	}
	
	while (!s2.empty()) {
		cout << s2.top()->val << " ";
		s2.pop();
	}
}
方法二: (非递归单栈式)
void PostorderTraversal2(TreeNode* root) {
	if (root == nullptr)
		return;
	stack<TreeNode*> s1;
	TreeNode* h = root;
	TreeNode* c = nullptr;
	s1.push(h);
	c = s1.top();
	while (!s1.empty()) {
		if (c->left && h != c->left && h != c->right) {
			s1.push(c->left);
		}
		else if (c->right && h != c->right) {
			s1.push(c->right);
		}
		else {
			c = s1.top();
			cout << c->val << " ";
			s1.pop();
			h = c;
		}
		if(!s1.empty())
			c = s1.top();
	}
}
二叉树按层遍历

宽度优先遍历常用队列结构,连同行号打印

可用last(正在打印当前行的最右节点)和nlast(表示下一行的最右节点)两个变量来操作

二叉树的序列化和反序列化

序列化:前中后遍历和按层遍历方式

字符串中空可以用#表示,结束可以用!表示

反序列化:将字符串按照!分割,再按照序列化规则进行反序列化即可

二叉树的子树

任何一个以节点为头部的整棵树。

平衡二叉树(AVL树)

1.空树是平衡二叉树

2.一棵树不为空,并且所有子树都满足各自的左子树和右子树的高度差不超过1

判断树是否为平衡二叉树
搜索二叉树

特征:每棵子树的头节点的值比各自左子树的所有节点值要大,也都比各自右子树上的所有节点要小。

中序遍历得到的序列,一定是从小到大排列的。

红黑树、平衡二叉树等,其实都是搜索二叉树的不同实现。(提高效率)

给头节点,判断是否为搜索二叉树

用非递归的中序遍历可以实现:每次遍历值比上一个大

满二叉树

除最右一层的节点无任何节点外,剩下的每一层的节点都有两个子节点。

节点数=2的层数次方 - 1,层数=log以2为底的(节点数+1)

完全二叉树

除了最右一层外,其他层节点数都是满的,最后一层缺少的节点都集中在右边。

给头节点,判断是否为完全二叉树

可用按层遍历二叉树的方式,按照定义判断

面试与工程上的二叉树节点类型

面试中包含:数据项、左孩子、有孩子

工程上往往多一条指向父节点的指针。

后继节点

这个节点在中序遍历序列中的下一个节点。

前驱节点

这个节点在中序遍历序列中的上一个节点。

纸张的连续对折产生的上下凹痕可以产生一个满二叉树
二叉树中两节点最远距离有三种情况

1.左子树上最大距离

2.右子树上最大距离

3.左子树上离左孩子最大距离+头节点自身+右子树上离右孩子最大距离

123者间最大的就是两节点最大距离

二叉树遍历的改写需要熟练掌握
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值