Algorithm problem of binary tree

Table of contents

1. Non-recursive form realizes front-middle-back order traversal

1.1 Preorder traversal

1.2 Post-order traversal (using two stacks)

1.3 Post-order traversal (using a stack) show operation

1.4 Inorder traversal

​edit

2. Realize layer-by-layer traversal of binary tree

1. Use the queue

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


 

Guess you like

Origin blog.csdn.net/flyingcloud6/article/details/128873987