Table of contents
1. Non-recursive form realizes front-middle-back order traversal
1.2 Post-order traversal (using two stacks)
1.3 Post-order traversal (using a stack) show operation
2. Realize layer-by-layer traversal of binary tree
3. Count the layers with the most binary trees
The structure of a binary tree:
class Node {
public:
Node(int v) {
value = v;
}
public:
int value;
Node* left;
Node* right;
};
1. Non-recursive form realizes front-middle-back order traversal
1.1 Preorder traversal
1. Print as soon as it pops up
2. If there is a right, press the right
3. If left, press the left
void pre(Node* head) {
cout << "前序遍历:" << endl;
if (head != nullptr) {
stack<Node*> stack;
stack.push(head);
while (!stack.empty()) {
head = stack.top();
stack.pop();
cout << head->value << " ";
if (head->right != nullptr) {
stack.push(head->right);
}
if (head->left != nullptr) {
stack.push(head->left);
}
}
}
cout << endl;
}
1.2 Post-order traversal (using two stacks)
Does the order of head right left look familiar? That's right, isn't it the reverse order traversal?
1. Pop it into the second stack res
2. If left, press the left
3. If there is a right, press the right
4. Finally, print all in res
void pos(Node* head) {
cout << "后序遍历:" << endl;
if (head != nullptr) {
stack<Node*> st1;
stack<Node*> st2;
st1.push(head);
while (!st1.empty()) {
head = st1.top();
st1.pop();
st2.push(head);
if (head->left != nullptr) {
st1.push(head->left);
}
if (head->right != nullptr) {
st1.push(head->right);
}
}
while (!st2.empty()) {
cout << st2.top()->value << " ";
st2.pop();
}
}
cout << endl;
}
1.3 Post-order traversal (using a stack) show operation
Only use one stack to complete
void pos2(Node* h) {
cout<<"后序遍历炫技版: "<<endl;
if (h != nullptr) {
stack<Node*> stack;
stack.push(h);
Node* c = nullptr;
while (!stack.empty()) {
c = stack.top();
//说明这个c的左树都还没处理呢,肯定先要去处理左树
if (c->left != nullptr && h != c->left && h != c->right) {
stack.push(c->left);
}
//说明左树处理了,但右树没有处理,那就去处理右树
else if (c->right != nullptr && h != c->right) {
stack.push(c->right);
}
//左右树都处理完了,那就去处理头
else {
cout << stack.top()->value<<" ";
stack.pop();
h = c;//处理一个,那就让h记录刚处理的位置
}
}
}
cout << endl;
}
1.4 Inorder traversal
1. Push the entire left border onto the stack in sequence
2. 1 If it cannot be executed, pop the stack and continue execution on the popped right tree
Why do you do this?
void in(Node* cur) {
cout<<"中序遍历 : "<<endl;
if (cur != nullptr) {
stack<Node*> stack;
while (!stack.empty() || cur != nullptr) {
if (cur != nullptr) {
stack.push(cur);
cur = cur->left;
}
else {
cur = stack.top();
stack.pop();
cout << cur->value << " ";
cur = cur->right;
}
}
}
cout << endl;
}
2. Realize layer-by-layer traversal of binary tree
1. Use the queue
Print when it pops up, advance to the left tree, then enter the right tree
void level(Node* head) {
if (head == nullptr) {
return;
}
queue<Node*> queue;
queue.push(head);
while (!queue.empty()) {
Node* cur = queue.front();
cout << cur->value << " ";
queue.pop();
//System.out.println(cur.value);
if (cur->left != nullptr) {
queue.push(cur->left);
}
if (cur->right != nullptr) {
queue.push(cur->right);
}
}
}
You can also use the method of the answer given by Niuke: realize zigzag printing
vector<vector<int> > levelOrder(TreeNode* root) {
// write code here
vector<vector<int>> vt;
if(root==nullptr)
return vt;
//队列存储,进行层次遍历
queue<TreeNode*> q;
q.push(root);
TreeNode* cur;
while(!q.empty()){
vector<int> temp;
int n=q.size();
for(int i=0;i<n;++i){
cur=q.front();
q.pop();
temp.push_back(cur->val);
if(cur->left)
q.push(cur->left);
if(cur->right)
q.push(cur->right);
}
vt.push_back(temp);//一层都统计完之后再加入
}
return vt;
}
3. Count the layers with the most binary trees
Not only to print each layer, but also to discover where a layer starts or ends
1. Use map
int maxWidthUseMap(Node* head) {
if (head == nullptr) {
return 0;
}
queue<Node*> queue;
queue.push(head);
// key 在 哪一层,value
unordered_map <Node*, int> levelMap;
levelMap.insert(make_pair(head,1));
int curLevel = 1; // 当前你正在统计哪一层的宽度
int curLevelNodes = 0; // 当前层curLevel层,宽度目前是多少
int Max = 0;
while (!queue.empty()) {
Node* cur = queue.front();
queue.pop();
int curNodeLevel = levelMap[cur];//当前的层数
if (cur->left != nullptr) {
levelMap.insert(make_pair(cur->left, curNodeLevel + 1));
queue.push(cur->left);
}
if (cur->right != nullptr) {
levelMap.insert(make_pair(cur->right, curNodeLevel + 1));
queue.push(cur->right);
}
if (curNodeLevel == curLevel) {
curLevelNodes++;
}
else {
Max = max(Max, curLevelNodes);
curLevel++;
curLevelNodes = 1;//刚开始的时候下一层肯定是1
}
}
Max = max(Max, curLevelNodes);
return Max;
}
2, no map
int maxWidthNoMap(Node* head) {
if (head == nullptr) {
return 0;
}
queue<Node*> queue;
queue.push(head);
Node* curEnd = head; // 当前层,最右节点是谁
Node* nextEnd = nullptr; // 下一层,最右节点是谁
int Max = 0;
int curLevelNodes = 0; // 当前层的节点数
while (!queue.empty()) {
Node* cur = queue.front();
queue.pop();
if (cur->left != nullptr) {
queue.push(cur->left);
nextEnd = cur->left;
}
if (cur->right != nullptr) {
queue.push(cur->right);
nextEnd = cur->right;
}
curLevelNodes++;
if (cur == curEnd) {
Max = max(Max, curLevelNodes);
curLevelNodes = 0;
curEnd = nextEnd;
}
}
return Max;
}
Question: Given a node in a binary tree, return its successor node
The successor node refers to the next node traversed by him in order
1. Violence:
The easiest way is to keep looking for the parent until you find the parent node, and then traverse in order to find his next node.
2. Go directly to his successor
Since it is an in-order traversal, it must follow the order of left head right,
Then if a tree has a right subtree , its successor is directly the leftmost subtree of the right subtree
If there is no right subtree , keep going up until the parent-child relationship is that the subtree is the left subtree of the parent, (for the right subtree, continue to go up)
Of course, the last node has no successor, so it must not be found, so just return nullptr
code:
Node* getSuccessorNode(Node* node) {
if (node == nullptr) {
return node;
}
if (node->right != nullptr) {
return getLeftMost(node->right);
}
else { // 无右子树
Node* parent = node->parent;
while (parent != nullptr && parent->right == node) { // 当前节点是其父亲节点右孩子
node = parent; // 那就继续向上去找
parent = node->parent;
}
return parent;
}
}
Node* getLeftMost(Node* node) {
if (node == nullptr) {
return node;
}
while (node->left != nullptr) {
node = node->left;
}
return node;
}
In the same way, looking for the front drive is just the other way around.
This tree does not exist at all, but I simulated it with recursion
The clearly specified tree can be printed without building a tree at all