这三种常见的扁历方式,是考研面试等场合经常遇到的,在此做一个总结。
1、前序遍历比较简单:用指针p指向根节点,若p!=NULL且栈非空,则直接访问节点,并将节点的右孩子入栈,同时指针p向左孩子移动。
2、中序扁历:用指针p指向根节点,若p!=NULL且栈非空,则当前节点入栈,同时指针p向左孩子移动,出栈是指针指向当前节点的右孩子。
3、后序扁历相对复杂:需要设置一个辅助栈,标识该节点是否是第二次出栈,只有第二次出栈的节点才可被访问。
具体实现就不啰嗦了,直接上代码吧!
#include <stack> #include <queue> using namespace std; // Binary tree struct struct BinaryTreeNode { BinaryTreeNode() :m_nValue(0), m_pLeft(NULL), m_pRight(NULL){} int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; // 按层次创建节点 BinaryTreeNode* CreateBinaryTree() { int a; BinaryTreeNode *t = NULL; queue<BinaryTreeNode*> queue_nodes; cout << "Enter the value of current node value, (space to the leaf node)." << endl; if (cin >> a && a != -1) { t = new BinaryTreeNode; t->m_nValue = a; queue_nodes.push(t); } while (!queue_nodes.empty()) { BinaryTreeNode *tNode = queue_nodes.front(); queue_nodes.pop(); if (cin >> a && a != -1) { BinaryTreeNode *newLeftNode = new BinaryTreeNode; newLeftNode->m_nValue = a; tNode->m_pLeft = newLeftNode; queue_nodes.push(newLeftNode); } if (cin >> a && a != -1) { BinaryTreeNode *newRightNode = new BinaryTreeNode; newRightNode->m_nValue = a; tNode->m_pRight = newRightNode; queue_nodes.push(newRightNode); } } return t; } void PreOrderTraverse(BinaryTreeNode *t, void(*visit)(int)) { stack<BinaryTreeNode*> stack_nodes; BinaryTreeNode *p = t; while (p || !stack_nodes.empty()) { if (p){ visit(p->m_nValue); if (p->m_pRight) stack_nodes.push(p->m_pRight); p = p->m_pLeft; } else{ p = stack_nodes.top(); stack_nodes.pop(); } } } void InOrderTraverse(BinaryTreeNode *t, void(*visit)(int)) { stack<BinaryTreeNode*> stack_nodes; BinaryTreeNode *p = t; while (p || !stack_nodes.empty()) { if (p){ stack_nodes.push(p); p = p->m_pLeft; } else{ p = stack_nodes.top(); stack_nodes.pop(); visit(p->m_nValue); p = p->m_pRight; } } } void PostOrderTraverse(BinaryTreeNode *t, void(*visit)(int)) { stack<BinaryTreeNode*> stack_nodes; stack<bool> stack_visited; // 辅助栈,标识节点是否已经出过栈,只有第二次出栈的节点才能被访问 BinaryTreeNode *p = t; bool visited = false; while (p || !stack_nodes.empty()) { if (p){ stack_nodes.push(p); // 当前节点入栈 stack_visited.push(false); // 对应的辅助标识入栈 p = p->m_pLeft; // 对左孩子进行操作 } else{ p = stack_nodes.top(); stack_nodes.pop(); visited = stack_visited.top(); stack_visited.pop(); if (!visited){ stack_nodes.push(p); stack_visited.push(true); p = p->m_pRight; // 对第一次出栈的节点,入栈后跳转到其右孩子 } else{ visit(p->m_nValue); p = NULL; } } } }
时间: 2024-10-11 23:12:53