总链接:https://docs.qq.com/doc/DUHRtdXZZSWFkeGdE
非迭代版链接:
迭代版链接:代码随想录
144、前序遍历
链接:力扣
递归版:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: vector<int>v; vector<int> preorderTraversal(TreeNode* root) { preorder(root); return v; } void preorder(TreeNode *root) { if(root!=nullptr) { v.push_back(root->val); preorderTraversal(root->left); preorderTraversal(root->right); } } };
非递归版:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { //用栈,非递归写法 public: vector<int> preorderTraversal(TreeNode* root) { //创建栈 stack<TreeNode*>sta; //记录节点val的顺序 vector<int>v; TreeNode *node=root;//注意!!!root 先不压栈 while(!sta.empty()|| node!=nullptr) { //把所有左边的节点压入栈中 while(node!=nullptr) { v.push_back(node->val); sta.push(node); node=node->left; } node=sta.top();//pop出一个最后压栈的左节点 sta.pop(); node=node->right;//将node指针指向右边 } return v; } };
因为这里只注意非递归迭代版,递归版只需要在原先的基础上 稍微改动一下顺序即可。
94、中序遍历(和前序遍历很像,只是加入值的时机不同)
链接:力扣
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { //非递归遍历 public: vector<int> inorderTraversal(TreeNode* root) { stack<TreeNode*>sta; vector<int>v; TreeNode *node=root; while(!sta.empty()|| node!=nullptr) { while(node!=nullptr) { sta.push(node); node=node->left; } node =sta.top(); //中序遍历位置 v.push_back(node->val); sta.pop(); node=node->right; } return v; } };
145. 二叉树的后序遍历
链接:力扣
class Solution { public: vector<int> postorderTraversal(TreeNode* root) { stack<TreeNode*> st; vector<int> result; if (root == NULL) return result; st.push(root); while (!st.empty()) { TreeNode* node = st.top(); st.pop(); result.push_back(node->val); if (node->left) st.push(node->left); // 相对于前序遍历,这更改一下入栈顺序 (空节点不入栈) if (node->right) st.push(node->right); // 空节点不入栈 } reverse(result.begin(), result.end()); // 将结果反转之后就是左右中的顺序了 return result; } };
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { //非递归写法,后序遍历,啊啊啊啊好难啊先不写了 //首先是官方题解中用到了pre的辅助指针,我不好理解,因此选择了代码随想录的解法,即后序遍历是左右中,中序遍历是中左右, // 中序遍历压栈时,中序遍历先压右节点,再压左节点,后序遍历在中序遍历基础上修改,中右左,再reverse,故先压左节点,再压右节点 public: vector<int> postorderTraversal(TreeNode* root) { vector<int>v; stack<TreeNode*>sta; if(root==nullptr) { return v; } sta.push(root); while(!sta.empty()) { TreeNode *top=sta.top(); sta.pop(); v.push_back(top->val);//v中记录 //压左节点 if(top->left!=nullptr) { sta.push(top->left); } if(top->right!=nullptr) { sta.push(top->right); } } reverse(v.begin(),v.end()); return v; } };
102、层序遍历
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { //我最喜欢的层序遍历!!queue public: vector<vector<int>> levelOrder(TreeNode* root) { queue<TreeNode*>q; vector<vector<int>>v; //vector<int>mv; if(root==nullptr) { return v; } else { q.push(root); while(!q.empty()) { int len=q.size(); vector<int>mv; for(int i=0;i<len;i++) { TreeNode *temp=q.front(); mv.push_back(temp->val); q.pop(); if(temp->left!=nullptr) { q.push(temp->left); } if(temp->right!=nullptr) { q.push(temp->right); } } v.push_back(mv); } return v; } } };
51.N皇后 (经典回溯法)
class Solution { public: //令我多次失败的n皇后问题 //皇后不能在同一行、同一列、同一斜线上 /*其中,不在同一行可以用i来保证, 不在同一列要遍历之前已经安放的棋子,保证(x,y) 和(x1,y1)(x2,y2)的任何y都不同; 不在同一斜线要求abs(x1-x)!=abs(y1-y) */ vector<vector<string>> v; vector<string>board;//记录的棋盘 bool if_true(vector<string> &board,int x,int y) { int n=board.size(); //对于是否同一列 for(int i=0;i<x;i++) { if(board[i][y]=='Q')//是一列的 { return false; } } //对于左上角的斜线 int tempx=x-1; int tempy=y-1; while(tempx>=0 && tempy>=0) { if(board[tempx][tempy]=='Q') { return false; } tempx--; tempy--; } //对于右上角斜线 int tx=x-1; int ty=y+1; while(tx>=0 && ty<n) { if(board[tx][ty]=='Q') { return false; } tx--; ty++; } return true; } void dfs(vector<string> &board,int n,int i) { if(i==n) { v.push_back(board); } else { for(int j=0;j<n;j++) { //当前坐标节点为(i,j) if(if_true(board,i,j)) { board[i][j]='Q'; dfs(board,n,i+1); board[i][j]='.'; } } } } vector<vector<string>> solveNQueens(int n) { this->board.resize(n,string(n,'.')); dfs(board,n,0);//从第0行开始 return v; } };
注:一开始写了三个函数,分别判断是否在同一列、同一左右斜线,然后超时了。
另外,棋盘类型是vector<string>,一开始写成了vector<vector<string>>,还查了怎么初始化,报了几次错。