二元树:
每个节点有两个子节点,左子节点和右子节点。
节点结构:
typedef struct NODE
{
char val;
NODE *left;
NODE *right;
} NODE ;
生成二元树:
利用递归算法,不断生成新的节点,并加入树中,‘#’代表空节点
NODE* TreeConstructor() { char ch; cin>>ch; NODE *root; if (ch=='#') { return NULL; } else { root=new NODE; root->val=ch; root->left=TreeConstructor(); root->right=TreeConstructor(); return root; } }
遍历二元树:
深度遍历二元树:利用stl容器stack实现,节点先进后出,先入右节点,后入左节点,即先进后出、先右后左;
步骤:
1,入根节点;
2,出栈顶元素;
3,若栈顶元素右孩子非空,入栈;
4,若栈顶元素左孩子非空,入栈;
5,若栈非空,转向2.
void depthFirstSearch(NODE *root)
{
stack<NODE*> NODE_stack;
NODE_stack.push(root);
NODE *node;
while(!NODE_stack.empty())
{
node=NODE_stack.top();
NODE_stack.pop();
cout<<node->val<<" ";
if (node->right!=NULL)
{
NODE_stack.push(node->right);
}
if (node->left!=NULL)
{
NODE_stack.push(node->left);
}
}
}
广度遍历二元树:利用stl容器queue实现,节点先进先出,先入左节点,后入右节点,即先进先出、先左后右;
步骤:
1,入根节点;
2,出队首元素;
3,若队首元素左孩子非空,加入队尾;
4,若队首元素右孩子非空,加入队尾;
5,若队非空,转向2.
void breadFirstSearch(NODE *root)
{
queue<NODE*> NODE_queue;
NODE_queue.push(root);
NODE *node;
while(!NODE_queue.empty())
{
node=NODE_queue.front();
NODE_queue.pop();
cout<<node->val<<" ";
if (node->left!=NULL)
{
NODE_queue.push(node->left);
}
if (node->right!=NULL)
{
NODE_queue.push(node->right);
}
}
}
先序、中序、后序遍历:均采用递归算法;
最短路径:
方法一:利用递归算法
int minDepth(NODE *root) { if (root==NULL) return 0; if (root->left==NULL&&root->right==NULL) return 1; int leftDepth=minDepth(root->left); int rightDepth=minDepth(root->right); if (leftDepth==0) { return rightDepth+1; } if (rightDepth==0) { return leftDepth+1; } return min(leftDepth,rightDepth)+1; }
假设有如下树:
递归演示图如下:
其中1,2,3,4,5,6指的是运行的步骤,由左向右依次调用minDepth函数,黑线为初始进入函数,函数为函数返回路线。
方法二:
对二叉树进行BFS,由于是按层遍历的,因此如果在某一层发现了一个叶子节点,那么就找到了最小深度,此时返回当前深度即可。
代码如下:
int minDepth1(NODE *root) { if (root == NULL) return 0; int depth = 1; int currentLevel = 1; int nextLevel = 0; queue<NODE*> NODE_queue; NODE_queue.push(root); while (!NODE_queue.empty()) { NODE *node = NODE_queue.front(); NODE_queue.pop(); currentLevel--; if (node->left == NULL && node->right == NULL) { return depth; } if (node->left != NULL) { NODE_queue.push(node->left); nextLevel++; } if (node->right != NULL) { NODE_queue.push(node->right); nextLevel++; } if (currentLevel == 0) { if (nextLevel != 0) { depth++; } currentLevel = nextLevel; nextLevel = 0; } } return depth; }
完整代码如下:
binary_tree.h
#include <iostream> #include <queue> #include <stack> #include <vector> #include <algorithm> using namespace std; typedef struct NODE { char val; NODE *left; NODE *right; } NODE ; enum ORDER_MODE { ORDER_MODE_PREV = 0, ORDER_MODE_MID, ORDER_MODE_POST };//枚举,代表遍历树的方式(前序,中序,后序) NODE* TreeConstructor(); void depthFirstSearch(NODE *root); void breadFirstSearch(NODE *root); int minDepth(NODE *root); int minDepth1(NODE *root); void printTree(ORDER_MODE method,NODE *root); void printTreeInPre(NODE *root) ; void printTreeInMid(NODE *root) ; void printTreeInPost(NODE *root) ;
main.cpp:
#include "binary_tree.h" int index=0; NODE* TreeConstructor() { char ch; cin>>ch; NODE *root; if (ch=='#') { return NULL; } else { root=new NODE; root->val=ch; root->left=TreeConstructor(); root->right=TreeConstructor(); return root; } } void depthFirstSearch(NODE *root) { stack<NODE*> NODE_stack; NODE_stack.push(root); NODE *node; while(!NODE_stack.empty()) { node=NODE_stack.top(); NODE_stack.pop(); cout<<node->val<<" "; if (node->right!=NULL) { NODE_stack.push(node->right); } if (node->left!=NULL) { NODE_stack.push(node->left); } } } void breadFirstSearch(NODE *root) { queue<NODE*> NODE_queue; NODE_queue.push(root); NODE *node; while(!NODE_queue.empty()) { node=NODE_queue.front(); NODE_queue.pop(); cout<<node->val<<" "; if (node->left!=NULL) { NODE_queue.push(node->left); } if (node->right!=NULL) { NODE_queue.push(node->right); } } } int minDepth(NODE *root) { if (root==NULL) return 0; if (root->left==NULL&&root->right==NULL) return 1; int leftDepth=minDepth(root->left); int rightDepth=minDepth(root->right); if (leftDepth==0) { return rightDepth+1; } if (rightDepth==0) { return leftDepth+1; } return min(leftDepth,rightDepth)+1; } int minDepth1(NODE *root) { if (root == NULL) return 0; int depth = 1; int currentLevel = 1; int nextLevel = 0; queue<NODE*> NODE_queue; NODE_queue.push(root); while (!NODE_queue.empty()) { NODE *node = NODE_queue.front(); NODE_queue.pop(); currentLevel--; if (node->left == NULL && node->right == NULL) { return depth; } if (node->left != NULL) { NODE_queue.push(node->left); nextLevel++; } if (node->right != NULL) { NODE_queue.push(node->right); nextLevel++; } if (currentLevel == 0) { if (nextLevel != 0) { depth++; } currentLevel = nextLevel; nextLevel = 0; } } return depth; } void printTree(ORDER_MODE method,NODE *root) { if (ORDER_MODE_PREV==method) { printTreeInPre(root); } if (ORDER_MODE_MID==method) { printTreeInMid(root); } if (ORDER_MODE_POST==method) { printTreeInPost(root); } }; void printTreeInPre(NODE *root) { if (root) { cout<<root->val<<" "; printTreeInPre(root->left); printTreeInPre(root->right); } } void printTreeInMid(NODE *root) { if (root) { printTreeInMid(root->left); cout<<root->val<<" "; printTreeInMid(root->right); } } void printTreeInPost(NODE *root) { if (root) { printTreeInPost(root->left); printTreeInPost(root->right); cout<<root->val<<" "; } } void main() { NODE *root; root=TreeConstructor(); cout<<"深度遍历:"; depthFirstSearch(root); cout<<endl<<"广度遍历:"; breadFirstSearch(root); cout<<endl<<"先序遍历:"; printTree(ORDER_MODE_PREV,root); cout<<endl<<"中序遍历:"; printTree(ORDER_MODE_MID,root); cout<<endl<<"后序遍历:"; printTree(ORDER_MODE_POST,root); cout<<endl<<"最小路径:"; int min1= minDepth(root); cout<<min1<<" "; int min2=minDepth1(root); cout<<min2; }
运行一次结果为: