填个坑-二叉树层次遍历及应用

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/NICE__FUTURE/article/details/86599166

有一篇旧文写的是在终端或文件中图形化打印二叉树,当时使用了 队列 ,但后来在学到二叉树的 层次遍历 的时候才意识到当时的实现是真的……蹩脚。

二叉树的层次遍历

如图所示二叉树:

        .--------- 1 ---------.
  .---- 2 ----.          .----3----.
  4           5          6         7
层次遍历结果:1 2 3 4 5 6 7

层次遍历符合先入先出 FIFO 的原则,适合使用 队列 来实现

过程描述:
1 入队 queue: 1
1 出队,打印 1,1 的左结点 2 入队,右结点 3 入队 queue: 2, 3
2 出队,打印 2,2 的左结点 4 入队,右结点 5 入队 queue: 3, 4, 5
3 出队,打印 3,3 的左结点 6 入队,右结点 7 入队 queue: 4, 5, 6, 7
4 出队,打印 4,4 的左结点为 null,不入队,右结点为 null, 不入队 queue: 5, 6, 7
5 出队,打印 5,5 的左结点为 null,不入队,右结点为 null, 不入队 queue: 6, 7
6 出队,打印 6,6 的左结点为 null,不入队,右结点为 null, 不入队 queue: 7
7 出队,打印 7,7 的左结点为 null,不入队,右结点为 null, 不入队 queue:
队空,遍历结束

代码示例:(用Java写过,就直接贴上来了)

	//levelorder 
	public void levelorder() {
		System.out.println("levelorder:");
		LinkedQueue<BinaryNode<T>> queue = new LinkedQueue<BinaryNode<T>>();
		queue.add(root);
		while (!queue.isEmpty()) {
			BinaryNode<T> p = queue.poll();
			System.out.print(p.toString() + " ");
			if (p != null) {
				if (p.left != null) queue.add(p.left);
				if (p.right != null) queue.add(p.right);
			}
		}
		System.out.println();
	}

层次遍历的应用(其实是填坑)

当时写在 BinaryTree 类中,作为成员方法

	/*打印树(含线条)*/
	public void showTree() {
		System.out.println("showTree:");
		LinkedQueue<ShowTreeNode<T>> queue = new LinkedQueue<ShowTreeNode<T>>();
		
		int height = this.getHeight();
		
		queue.add(new ShowTreeNode<T>(this.root, height+1));
		queue.add(new ShowTreeNode<T>(null, -1));
		
		while (height > 0) {
			ShowTreeNode<T> p = queue.poll();  //拿到当前结点
			if (p.height == -1) {
				height--;
				System.out.println();
				continue;
			}
			p.show();  //按格式打印当前结点
			if (p.treeNode != null) {
				queue.add(new ShowTreeNode<T>(p.treeNode.left, height));
				queue.add(new ShowTreeNode<T>(p.treeNode.right, height));
			} else {
				queue.add(new ShowTreeNode<T>(null, height));
				queue.add(new ShowTreeNode<T>(null, height));
			}
			if (queue.peek().height == -1) queue.add(new ShowTreeNode<T>(null, -1));  //换行标记,被标记结点的右子树继续被标记(换行)
		}
		System.out.println();
	}

这是另写的一个节点类

/*用于打印树的结点类(自定义)*/
class ShowTreeNode<T> {
	BinaryNode<T> treeNode;
	int height, width;
	
	public ShowTreeNode(BinaryNode<T> treeNode, int height) {
		this.treeNode = treeNode;
		this.height = height;
		this.width = (int) Math.pow(2, height);
	}
	
	public void show() {
		int num = width / 4;
		if (this.treeNode != null) {
			printBlocks('l', num);  //打印数据前的空白,'l'表示"left"
			printLines('l', num);  //打印数据前的短横线
			System.out.print(this.treeNode.data.toString());  //打印当前队列节点的数据
			printLines('r', num);  //打印数据后的短横线,'r'表示"right"
			printBlocks('r', num);  //打印数据后的空白
		} else {
			printBlocks('l', num*2);
			System.out.print(" ");
			printBlocks('r', num*2);
		}
	}
	
	//打印空白块的函数,此方法不用对外开放
	private void printBlocks(char opt, int num)
	{
		if (opt == 'l') {  //打印数据左边的空白
			while (num > 0)
			{
				System.out.print(" ");
				num--;
			}
		}
		else if (opt == 'r') {  //打印数据右边的空白
			while (num > 1)
			{
				System.out.print(" ");
				num--;
			}
		}
	}

	private void printLines(char opt, int num)
	{
		if (opt == 'l') {  //打印数据左边的短横线
			if (num > 0) System.out.print(".");
			while (num > 1)
			{
				System.out.print("-");
				num--;
			}
		}
		else if (opt == 'r') {  //打印数据右边的短横线
			while (num > 1)
			{
				System.out.print("-");
				num--;
			}
			System.out.print(".");
		}
	}
}

效果
参考上面说明层次遍历时展示的那棵二叉树

over
顺便填了填坑,凑合看了

展开阅读全文

没有更多推荐了,返回首页