Problema de algoritmo de árbol binario

Tabla de contenido

1. La forma no recursiva realiza un recorrido de orden frontal-medio-posterior

1.1 Travesía de pedido anticipado

1.2 Recorrido posterior al pedido (usando dos pilas)

1.3 Operación de mostrar el recorrido posterior al pedido (usando una pila)

1.4 Recorrido en orden

editar

2. Realice el recorrido capa por capa del árbol binario

1. Usa la cola

3. Cuente las capas con más árboles binarios


La estructura de un árbol binario:

class Node {
public:
	Node(int v) {
		value = v;
	}
public:
	int value;
	Node* left;
	Node* right;

};

1. La forma no recursiva realiza un recorrido de orden frontal-medio-posterior

1.1 Travesía de pedido anticipado

1. Imprima tan pronto como aparezca

2. Si hay un derecho, presione el derecho

3. Si la izquierda, presione la izquierda

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 Recorrido posterior al pedido (usando dos pilas)

 ¿Te resulta   familiar el orden de la cabeza a la derecha a la izquierda ? Así es, ¿no es el recorrido en orden inverso?

1. Póngalo en la segunda pila res

2. Si la izquierda, presione la izquierda

3. Si hay un derecho, presione el derecho

4. Finalmente, imprima todo en 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 Operación de mostrar el recorrido posterior al pedido (usando una pila)

Solo use una pila para completar

	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 Recorrido en orden

 1. Empuje todo el borde izquierdo en la pila en secuencia

 2. 1 Si no se puede ejecutar, abre la pila y continúa la ejecución en el árbol derecho abierto

¿Por qué haces esto?

	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. Realice el recorrido capa por capa del árbol binario

1. Usa la cola

Imprima cuando aparezca, avance al árbol de la izquierda, luego ingrese al árbol de la derecha

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);
			}
		}
	}

También puede usar el método de la respuesta dada por Niuke: realizar la impresión en zigzag

  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. Cuente las capas con más árboles binarios

No solo para imprimir cada capa, sino también para descubrir dónde comienza o termina una capa

1. Usa el mapa

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, sin mapa

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;
	}

Pregunta: dado un nodo en un árbol binario, devolver su nodo sucesor

 El nodo sucesor se refiere al siguiente nodo atravesado por él para

1. Violencia:   

 La forma más sencilla es seguir buscando el nodo principal hasta que encuentre el nodo principal y luego atravesarlo para encontrar el siguiente nodo.

2. Ir directamente a su sucesor

Como es un recorrido en orden, debe seguir el orden de izquierda cabeza derecha,

Entonces, si un árbol tiene un subárbol derecho , su sucesor es directamente el subárbol más a la izquierda del subárbol derecho.

 Si no hay un subárbol derecho , siga subiendo hasta que la relación padre-hijo sea que el subárbol es el subárbol izquierdo del padre (para el subárbol derecho, continúe subiendo)

 Por supuesto, el último nodo no tiene sucesor, por lo que no debe encontrarse, así que simplemente devuelva nullptr

código:

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;
	}

De la misma manera, buscar la tracción delantera es justo al revés.

 Este árbol no existe en absoluto, pero lo simulé con recursividad.

El árbol claramente especificado se puede imprimir sin construir un árbol en absoluto


 

Supongo que te gusta

Origin blog.csdn.net/flyingcloud6/article/details/128873987
Recomendado
Clasificación