只会递归,迭代看完就忘,记录一下。
迭代其实与递归一样,递归隐式的维护了一个栈,而在迭代中需要我们显示的定义出来;依照不同的遍历顺序,将结点依次入栈,出栈。
时间按复杂度O(n),空间复杂度O(n)。
144. 二叉树的前序遍历
94. 二叉树的中序遍历
145. 二叉树的后序遍历
前序遍历
遍历顺序是 根结点 - 左子树结点 - 右子树结点,先将根结点存入栈,若栈不为空,取出栈头元素,存入栈头元素的右、左结点,一直重复,直到栈为空,一定是先存右结点,前序遍历是根-左-右,栈是先进后出,空结点不入栈。
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> s;
if(root == nullptr)
return result;
s.push(root); //存入根结点
while(!s.empty()){
TreeNode* head = s.top();
result.push_back(head->val);
s.pop(); //栈头出栈
if(head->right != nullptr) //右结点先入栈
s.push(head->right);
if(head->left != nullptr) //左结点再入栈
s.push(head->left);
}
return result;
}
中序遍历
遍历顺序是 左结点-根结点-右结点,需要用一个指针访问结点,指针指向根结点,若栈不为空或者指针不为空,如果指针不为空,把指针入栈,指针指向自己的左结点,否则指针指向栈头元素,指针指向自己的右结点,重复,直到指针为空且栈为空结束。
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> s;
if(root == nullptr)
return result;
TreeNode* head = root; //访问结点的指针
while(head != nullptr || !s.empty()){
if(head != nullptr){
s.push(head);
head = head->left; //左
}
else{
head = s.top();
result.push_back(head->val); //根
s.pop();
head = head->right; //右
}
}
return result;
}
后序遍历
遍历顺序是 左结点-右结点-根结点,对前序遍历调整一下顺序,得到根-右-左的遍历顺序,逆序数组,得到后序遍历。
vector<int> postorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> s;
if(root == nullptr)
return result;
s.push(root);
while(!s.empty()){
TreeNode* head = s.top();
result.push_back(head->val); //根
s.pop();
if(head->left != nullptr) //左
s.push(head->left);
if(head->right != nullptr) //右
s.push(head->right);
}
reverse(result.begin(), result.end()); //逆序
return result;
}