测试用树
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者间最大的就是两节点最大距离