3.二叉树的基本算法

对上课中所涉及到的代码题做一些总结
同样的首先给出以下数据结构:

class TreeNode {
public:
	TreeNode();
	TreeNode(int val);

	int val;
	TreeNode* left;
	TreeNode* right;

};

TreeNode::TreeNode():val(0),left(nullptr),right(nullptr) {

}


TreeNode::TreeNode(int val) {
	this->val = val;
	left = nullptr;
	right = nullptr;
}

1.二叉树的前序遍历递归

void test01(TreeNode* node) {
	if (node == nullptr) return;

	cout << node->val << endl;
	test01(node->left);
	test01(node->right);
}

2.二叉树的中序遍历递归

void test02(TreeNode* node) {
	if (node == nullptr) return;

	test02(node->left);
	cout << node->val << endl;
	test02(node->right);
}

3.二叉树的后序遍历递归

void test03(TreeNode* node) {
	if (node == nullptr) return;

	test03(node->left);
	test03(node->right);
	cout << node->val << endl;
}

4.二叉树的前序遍历非递归

void test04(TreeNode* node) {
	if (node == nullptr) return;
	stack<TreeNode*> s;
	s.push(node);
	while (!s.empty()) {
		TreeNode* tmp = s.top();
		s.pop();
		cout << tmp->val << endl;
		if (tmp->right != nullptr) {
			s.push(tmp->right);
		}
		if (tmp->left != nullptr) {
			s.push(tmp->left);
		}
	}

}

5.二叉树的中序遍历非递归

void test05(TreeNode* node) {
	if (node == nullptr) return;

	stack<TreeNode*> s;
	s.push(node);

	while (!s.empty()) {
		if (node->left != nullptr) {
			s.push(node->left);
			node = node->left;
		}
		else {
			cout << s.top()->val << endl;
			node = s.top()->right;
			s.pop();
		}
	}

;
}

6.二叉树的后序遍历非递归

void test06(TreeNode* node) {
	if (node == nullptr) return;
	if (node == nullptr) return;
	stack<TreeNode*> s;
	stack<int> sta;
	s.push(node);
	while (!s.empty()) {
		TreeNode* tmp = s.top();
		s.pop();
		sta.push(tmp->val);
		if (tmp->left != nullptr) {
			s.push(tmp->left);
		}
		if (tmp->right != nullptr) {
			s.push(tmp->right);
		}
	}
	while (!sta.empty()) {
		cout << sta.top() << endl;
		sta.pop();
	}
}

7.二叉树的层序遍历+最大宽度

void test07(TreeNode* node) {
	if (node == nullptr) return;

	//相比于层序遍历的时候,其实就相当于每次都记录一下size 最后返回size最大值即可。
	/*
	与左神思路相比 左神通过每次记录当前元素的层数,并且在压当前元素的左右子结点的时候,左右子结点的层数等于当前层结点
	的层数加1,最后记录即可。
	*/
	queue<TreeNode*> q;
	q.push(node);
	int maxLength = 0;
	while (!q.empty()) {
		int size = q.size();
		maxLength = std::max(maxLength, size);

		for (int i = 0; i < size; i++) {
			TreeNode* tmp = q.front();
			q.pop();
			cout << tmp->val << endl;

			if (tmp->left) {
				q.push(tmp->left);
			}
			if (tmp->right) {
				q.push(tmp->right);
			}
		}
	}
	return;
}

8.打印当前二叉树的后继结点

Node* test08(Node* node) {
	//分情况讨论
	//1. 如果当前结点有右子树,那么它的后继结点就是他右子树的最左节点
	//2. 如果当前结点没有右子树,那么他的后继结点就是向上遍历当为某个结点的左子树的时候,某个结点就是他的后继结点
	if (node == nullptr) {
		return node;
	}
	if (node->right != nullptr) {
		node = node->right;
		while (node->left != nullptr) {
			node = node->left;
		}
		return node;
	}
	else {
		Node* par = node->parent;
		while (par != nullptr && par->left != node) {
			node = par;
			par = node->parent;
		}

		return par;
	}

}

9. 纸条折痕打印问题

void test09(int n) {
	test09_1(1, n, true);
}

void test09_1(int i, int n, bool flag) {
	if (i > n) return;
	test09_1(i + 1, n, true);
	flag = flag == true ? 1 : 0;
	cout << flag<< endl;
	test09_1(i + 1, n, false);
}

10. 给定一颗二叉树的头节点head,返回这颗二叉树是不是平衡二叉树

struct Info {
	bool isBalace;
	int height;

	Info(bool flag, int h) {
		isBalace = flag;
		height = h;
	}
};

bool test10(TreeNode* node) {
	return test10_1(node)->isBalace;
}

Info* test10_1(TreeNode* node) {
	if (node == nullptr) {
		return new Info(true, 0);
	}
	Info* left = test10_1(node->left);
	Info* right = test10_1(node->right);
	
	int height = max(left->height, right->height) + 1;
	bool flag = true;

	if (left->isBalace || right->isBalace || abs(left->height - right->height) > 1) flag = false;
	return new Info(flag, height);
}

11. 给定一颗二叉树的头节点,任何两节点之间都存在距离,返回整颗二叉树的最大距离

struct NodeInfo_11 {
	int length;
	int maxLength;

	NodeInfo_11(int x,int y) {
		length = 0;
		maxLength = 0;
	}
};

NodeInfo_11* test11_1(TreeNode* head) {
	if (head == nullptr) {
		return new NodeInfo_11(0,0);
	}

	NodeInfo_11* leftMax = test11_1(head->left);
	NodeInfo_11* rightMax = test11_1(head->right);

	int heigh = std::max(leftMax->length, rightMax->length) + 1;
	int maxHeigh = std::max(std::max(leftMax->maxLength, rightMax->maxLength), leftMax->length + rightMax->length + 1);
	return new NodeInfo_11(heigh, maxHeigh);
}

int test11(TreeNode* head) {
	return test11_1(head)->maxLength;
}

12.给定一颗二叉树的头结点,返回这个二叉树的最大的二叉搜索树的个数

struct NodeInfo_12 {
	bool isAllBst;
	int maxSonTreeSize;
	int min;
	int max;

	NodeInfo_12(bool flag, int max, int left, int right) {
		this->isAllBst = flag;
		this->maxSonTreeSize = max;
		this->min = left;
		this->max = right;
	}
};

NodeInfo_12* test12_1(TreeNode* head) {
	if (head == nullptr) {
		return nullptr;
	}

	NodeInfo_12* leftInfo = test12_1(head->left);
	NodeInfo_12* rightInfo = test12_1(head->right);

	int min = head->val;
	int max = head->val;
	if (leftInfo) {
		min = std::min(min, leftInfo->min);
		max = std::max(max, leftInfo->max);
	}
	if (rightInfo) {
		min = std::min(min, rightInfo->min);
		max = std::max(max, rightInfo->max);
	}
	int maxSize = 0;
	if (leftInfo) {
		maxSize = leftInfo->maxSonTreeSize;
	}
	if (rightInfo) {
		maxSize = std::max(maxSize,rightInfo->maxSonTreeSize);
	}
	bool flag = false;
	if ((leftInfo == nullptr ? true : leftInfo->isAllBst) &&
		(rightInfo == nullptr ? true : rightInfo->isAllBst) &&
		(leftInfo == nullptr ? true : leftInfo->max < head->val) &&
		(rightInfo == nullptr ? true : rightInfo->min > head->val)) {
		flag = true;
		maxSize = leftInfo->maxSonTreeSize + rightInfo->maxSonTreeSize + 1;
	}

	return new NodeInfo_12(flag, maxSize, min, max);
}

int test12(TreeNode* head) {
	return test12_1(head)->maxSonTreeSize;
}

13.派对的最大快乐值

struct Employee {
	int happy;
	vector<Employee*> vecEmp;
	Employee(int x) {
		happy = x;
	}
};

struct Info_13 {
	int yes;
	int no;
	Info_13(int a, int b) {
		yes = a;
		no = b;
	}
};

Info_13* test13_1(Employee* x) {
	if (x->vecEmp.empty()) {
		return new Info_13(x->happy, 0);
	}

	int yes = x->happy;
	int no = 0;
	for (auto& e:x->vecEmp) {
		Info_13* tmp = test13_1(e);
		yes += tmp->no;
		no += std::max(tmp->no, tmp->yes);
	}
	return new Info_13(yes, no);
}

int test13(Employee* x) {
	Info_13* tmp = test13_1(x);
	return std::max(tmp->yes,tmp->no);
}

网课地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值