一、二叉树的遍历
1.深度优先遍历DFT
在先L后R的前提下:
1)前序遍历V-L-R
2)中序遍历L-V-R(递增序列)
3)后续遍历L-R-V
前序遍历递归方式:
vector<int> res;
vector<int> PreOrderDFS(TreeNode* root)
{//先序递归遍历
if(root==nullptr)//递归结束条件
return;
res.push_back(root->val); //先访问当前根节点
PreOrderDFS(root->left); //再访问当前节点的左子节点及其子树
PreOrderDFS(root->right); //最后访问当前节点的右子节点及其子树
return res;
}
中序遍历递归方式:
vector<int> res;
vector<int> InOrderDFS(TreeNode* root)
{//中序递归遍历
if(root == nullptr)//结束递归
return;
InOrderDFS(root->left); //先访问当前节点的左子节点及其子树
res.push_back(root->val); //再访问当前节点
InOrderDFS(root->right); //最后访问当前节点的右子节点及其子树
return res;
}
后续遍历递归方式:
vector<int> res;
vector<int> PostOrderDFS(TreeNode* root)
{//后序递归遍历
if(root == nullptr) //递归结束
return;
PostOrderDFS(root->left); //先访问当前节点的左子节点及其子树
PostOrderDFS(root->right);//再访问当前节点的右子节点及其子树
res.push_back(root->val); //最后访问当前节点
return res;
}
前序遍历非递归方式:
借助栈来实现,压入顺序为根、右、左。
出栈顺序对应为(根、左、右)
vetor<int> res;
vector PreOrderDFS(Node* root) //先打印当前遍历的节点再入栈
{
stack<Node *> nodeStack; //使用C++的STL标准模板库:栈
nodeStack.push(root);
while(!nodeStack.empty())
{
Node *node = nodeStack.top();
res.push_back(node->val); //访问根结点
nodeStack.pop();
//前序遍历一定要注意先压入当前节点的右孩子,因为栈是先进后出的结构
if(node->right)
nodeStack.push(node->right); //先将右子树压栈
if(node->left)
nodeStack.push(node->left); //再将左子树压栈
}
return res;
}
中序遍历非递归方式:
同样借助栈,需要注意的时进入循环的条件为栈是否为空或根节点是否为NULL,主要思路是首先将左节点入栈,重复该过程,直到左节点不存在,然后依次出栈,出栈的同时判断当前节点的右节点是否存在,若存在则再次进入循环。
vector<int> res;
vector<int> InOrderDFS(Node* root)
{
Stack<Node *> stack = nodeStack;
Node* node = root;
while (node != nullptr || !nodeStack.empty())
{
// 把当前节点的所有左子结点压入栈
while(node != nullptr)
{
nodeStack.push(node);
node = node->left;
}
// 访问节点,处理该节点的右子树
if(!stack.empty())
{
node = nodeStack.top();
res.push_back(node->val);//访问节点
node = nodeStack.pop();
node = node->right;
}
}
return res;
}
后续遍历非递归方式:
借助前序遍历,前序遍历为根左右,后序遍历为左右根,
只需将前序遍历顺序调整为根右左,再reverse翻转一下就可以得到后序遍历
vector<int> res;
vector<int> PostOrderDFS(Node* root)
{
Stack<Node *> stack = nodeStack;
Node* node = root;
while (node != null || !nodeStack.empty())
{
Node *node = nodeStack.top();
res.push_back(node->val); //访问根结点
nodeStack.pop();
//前序遍历一定要注意先压入当前节点的左孩子,因为栈是先进后出的结构
if(node->left)
nodeStack.push(node->left); //先将左子树压栈
if(node->right)
nodeStack.push(node->right); //再将右子树压栈
reverse(res.begin(),res.end());
}
return res;
}
2.广度优先遍历BFT(按层)
队列实现:
vector<int> res;
vector<int> BFT(Node* root)
{
queue<Node *> nodeQueue; //使用C++的STL标准模板库:队列
nodeQueue.push(root); //根节点入队
while(!nodeQueue.empty())
{
Node *node = nodeQueue.front();
nodeQueue.pop();
res.push_back(node->val); //访问根节点
if(node->left)
nodeQueue.push(node->left); //先将左子树入队
if(node->right)
nodeQueue.push(node->right); //再将右子树入队
}
return res;
}
二、图的搜索
1.深度优先搜索DFS(基于前序遍历)
2.广度优先搜索BFS