以此树为demo

先序遍历
定义:优先访问根节点,然后访问左子树,最后访问右子树,根节点->左子树->右子树
按照定义,那么上述demo的结果可以很好得出来:A->B->D->G->H->E->I->C->F
那么算法怎么实现呢?这里使用递归方法:
public static void nlr(TreeNode rootNode) {
TreeNode leftChild;
TreeNode rightNode;
if (rootNode != null) {
System.out.print(rootNode.data+" ");
leftChild = rootNode.leftChild;
nlr(leftChild);
rightNode = rootNode.rightChild;
nlr(rightNode);
}
}
运行结果如下:

中序遍历
定义:优先访问左子树,然后访问根节点,然后访问右子树,左子树->根节点->右子树
按照定义,那么上述demo的结果可以很好得出来:G->D->H->B->E-I->A->C->F
public static void lnr(TreeNode rootNode) {
TreeNode leftChild;
TreeNode rightNode;
if (rootNode != null) {
leftChild = rootNode.leftChild;
lnr(leftChild);
System.out.print(rootNode.data+" ");
rightNode = rootNode.rightChild;
lnr(rightNode);
}
}
运行结果如下:

后续遍历
定义:优先访问左子树,然后访问右子树,然后访问根节点,左子树->右子树->根节点
按照定义,那么上述demo的结果可以很好得出来:G->H->D->I->E->B->F->C->A
public static void lrn(TreeNode rootNode) {
TreeNode leftChild;
TreeNode rightNode;
if (rootNode != null) {
leftChild = rootNode.leftChild;
lrn(leftChild);
rightNode = rootNode.rightChild;
lrn(rightNode);
System.out.print(rootNode.data+" ");
}
}
运行结果如下:

按层遍历
定义:广度优先遍历,优先访问节点的左子树和右子树
使用队列方式来,每个节点判断一下有没有左右子树,有的话直接offer进队列,然后不停的输出队列即可
public static void storey(TreeNode rootNode) {
//使用队列,先进先出
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(rootNode);
while (!queue.isEmpty()) {
TreeNode t = queue.poll();
System.out.print(t.data+" ");
if (t.leftChild != null) {
queue.offer(t.leftChild);
}
if (t.rightChild != null) {
queue.offer(t.rightChild);
}
}
}
运行结果:

获取层数(获取二叉树最大深度)
相当于按层遍历的进阶了
public static void storey2(TreeNode rootNode) {
//使用队列,先进先出
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(rootNode);
int n;
int levelN = 1;
int count = 0;
System.out.print(rootNode.data);
while (!queue.isEmpty()) {
n = levelN; //上一层的节点数量赋值给n
levelN = 0; //清空leveN,开始重新计算当前行的节点数,给下一层使用
System.out.println();
for (int i=0;i<n;i++) { //n表示这一行的所有节点数量,n的值依赖于上一层的levelN的值
TreeNode t = queue.poll();
if (t.leftChild != null) {
queue.offer(t.leftChild);
levelN++; //节点数量+1
System.out.print(t.leftChild.data+" ");
}
if (t.rightChild != null) {
queue.offer(t.rightChild);
levelN++; //节点数量+1
System.out.print(t.rightChild.data+" ");
}
}
count++; //开始换行
}
System.out.print("行数:"+count);
}
运行结果如下:

优化写法:leftchild和rightchild offer进队列的时候,不急着poll出来,等到当前层的所有节点的左右子树都offer进去的时候,再进行下一次循环,这时候队列数量就是当前层的节点数量,然后继续下一层遍历,本质上和上文写的逻辑一样,只不过不需要额外的变量了。
public static void storey2(TreeNode rootNode) {
//使用队列,先进先出
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(rootNode);
int count = 0;
System.out.print(rootNode.data);
while (!queue.isEmpty()) {
int n = queue.size(); //临时保存队列数量,队列数量就是当前层节点数量
System.out.println();
for (int i=0;i<n;i++) { //循环当前层的节点数量
TreeNode t = queue.poll();
if (t.leftChild != null) {
queue.offer(t.leftChild);
System.out.print(t.leftChild.data+" ");
}
if (t.rightChild != null) {
queue.offer(t.rightChild);
System.out.print(t.rightChild.data+" ");
}
}
count++;
}
System.out.print("行数:"+count);
}
其他二叉树的进阶算法,后续记录在leetcode分类栏目中
1261

被折叠的 条评论
为什么被折叠?



