前序遍历
算法思想
前序遍历的思想是:
- 访问当前树的根节点
- 访问左子树
- 访问右子树
通俗的来说,每次访问到一个节点的时候,就先对这个节点进行操作(比如打印输出等),然后去访问它的左子树,再去访问它的右子树。
比如对于下面这个树:
1
/ \
2 3
/\ /\
4 5 6 7
前序遍历的步骤如下:
【1】首先访问节点1,对它进行输出操作,访问它的左子树。
节点1
-输出 √
-访问左子树
-访问右子树
输出:节点1
【2】进入节点1的左子树节点2,对它进行输出操作,访问它的左子树。
节点1
-输出 √
-访问左子树 -----> 节点2
-访问右子树 -输出 √
-访问左子树
-访问右子树
输出:节点1,节点2
【3】进入节点2的左子树节点4,对它进行输出操作,访问它的左子树。
节点1
-输出 √
-访问左子树 -----> 节点2
-访问右子树 -输出 √
-访问左子树 -----> 节点4
-访问右子树 -输出 √
-访问左子树
-访问右子树
输出:节点1,节点2,节点4
【4】节点4的左子树为空,进入右子树。
节点1
-输出 √
-访问左子树 -----> 节点2
-访问右子树 -输出 √
-访问左子树 -----> 节点4
-访问右子树 -输出 √
-访问左子树 √
-访问右子树
输出:节点1,节点2,节点4
【5】节点4的右子树为空,退出节点4。
节点1
-输出 √
-访问左子树 -----> 节点2
-访问右子树 -输出 √
-访问左子树 -----> 节点4
-访问右子树 -输出 √
-访问左子树 √
-访问右子树 √
输出:节点1,节点2,节点4
【5】进入节点2的右子树节点5,进行输出,访问它的左子树。
节点1
-输出 √
-访问左子树 ----------> 节点2
-访问右子树 -输出 √
-访问左子树 √
-访问右子树 ----- > 节点5
-输出 √
-访问左子树
-访问右子树
输出:节点1,节点2,节点4,节点5
【6】节点5的左子树为空,进入右子树。
节点1
-输出 √
-访问左子树 ----------> 节点2
-访问右子树 -输出 √
-访问左子树 √
-访问右子树 ----- > 节点5
-输出 √
-访问左子树 √
-访问右子树
输出:节点1,节点2,节点4,节点5
【7】节点5的右子树为空,退出节点5。
节点1
-输出 √
-访问左子树 ----------> 节点2
-访问右子树 -输出 √
-访问左子树 √
-访问右子树 ----- > 节点5
-输出 √
-访问左子树 √
-访问右子树 √
输出:节点1,节点2,节点4,节点5
【8】退出节点2,访问节点1的右子树。
节点1
-输出 √
-访问左子树 ----------> 节点2
-访问右子树 -输出 √
-访问左子树 √
-访问右子树 √
输出:节点1,节点2,节点4,节点5
【9】进入节点1的右子树节点3,对他进行输出,访问节点3的左子树。
节点1
-输出 √
-访问左子树 √
-访问右子树 ----- > 节点3
-输出 √
-访问左子树
-访问右子树
输出:节点1,节点2,节点4,节点5,节点3
【10】进入节点3的左子树节点6,对它进行输出,并访问它的左子树
节点1
-输出 √
-访问左子树 √
-访问右子树 ----- > 节点3
-输出 √
-访问左子树 -----> 节点6
-访问右子树 -输出 √
-访问左子树
-访问右子树
输出:节点1,节点2,节点4,节点5,节点3,节点6
【11】节点6的左子树为空,进入右子树。
节点1
-输出 √
-访问左子树 √
-访问右子树 ----- > 节点3
-输出 √
-访问左子树 -----> 节点6
-访问右子树 -输出 √
-访问左子树 √
-访问右子树
输出:节点1,节点2,节点4,节点5,节点3,节点6
【12】节点6的右子树为空,退出节点6
节点1
-输出 √
-访问左子树 √
-访问右子树 ----- > 节点3
-输出 √
-访问左子树 -----> 节点6
-访问右子树 -输出 √
-访问左子树 √
-访问右子树 √
输出:节点1,节点2,节点4,节点5,节点3,节点6
【13】进入节点3的右子树节点7,进行输出,然后访问它的左子树
节点1
-输出 √
-访问左子树 √
-访问右子树 ----- > 节点3
-输出 √
-访问左子树 √
-访问右子树-----> 节点7
-输出 √
-访问左子树
-访问右子树
输出:节点1,节点2,节点4,节点5,节点3,节点6,节点7
【14】节点7的左子树为空,进入右子树
节点1
-输出 √
-访问左子树 √
-访问右子树 ----- > 节点3
-输出 √
-访问左子树 √
-访问右子树-----> 节点7
-输出 √
-访问左子树 √
-访问右子树
输出:节点1,节点2,节点4,节点5,节点3,节点6,节点7
【15】节点7的右子树为空,退出节点7
节点1
-输出 √
-访问左子树 √
-访问右子树 ----- > 节点3
-输出 √
-访问左子树 √
-访问右子树-----> 节点7
-输出 √
-访问左子树 √
-访问右子树 √
输出:节点1,节点2,节点4,节点5,节点3,节点6,节点7
【16】退出节点3.
节点1
-输出 √
-访问左子树 √
-访问右子树 ----- > 节点3
-输出 √
-访问左子树 √
-访问右子树 √
输出:节点1,节点2,节点4,节点5,节点3,节点6,节点7
【17】 退出节点1,结束。
节点1
-输出 √
-访问左子树 √
-访问右子树 √
输出:节点1,节点2,节点4,节点5,节点3,节点6,节点7
递归实现
/*
对节点进行操作
*/
void visit(struct treeNode* node){
printf("%d ",node->val);
}
/*
前序遍历---递归
*/
void preOrderTraversal(struct treeNode *root){
if(root!=NULL){
visit(root);
preOrderTraversal(root->left);
preOrderTraversal(root->right);
}
}