一个查找链表结构二叉树最末结点的巧妙算法

算法第四版习题2.4.24: 用堆有序的二叉树实现一个优先队列,但使用链表结构,每个结点需要三个链接:两个向下,一个向上。要求算法基本操作所需时间为对数级。
二叉树如图:
图中第2层右侧应为3

此算法实现的主要步骤:
1.将新元素插入到最末结点之后,并上浮到合适位置
2. 从二叉树顶端删除最大元素,并将最末结点放到顶端,并下沉顶结点。
此算法的难点在于如何定位最末结点向后一位的结点

一、沈星繁博客中提出的解决办法

维护一个指向最末结点的指针,通过向上回溯来找下一位结点,如图:
此为沈星繁博客中的图片,借用一下
具体步骤为:
1.向上回溯一层,判断回溯方向:若为自左路回溯,则右路为后一位结点;若为右路回溯,转为第2步。
2.继续向上回溯,直到回溯方向为左路,然向向右下一层,再沿左路下到底。
3.若向上回溯一直为右路,则会回到顶结点,自顶结点一路向左下到底即可。
此算法逻辑较复杂,而且还要判断回溯方向。具体实现代码可参见下面链接: 沈星繁-算法2.4.

二、我的巧妙算法:

查找某序号结节位置(序号从1开始,自上而下自左到右顺序编号),对于二叉树来说,结点数为N,其下一位就是序号N+1的结点位置。具体查找方法如下:
1.先将序号转为二进制数。
2.此二进制数的位数代表二叉树的层数。自左向右分别为顶结点-2层结点-3层结点-4层结点。除第1位顶结点外,其余每位0代表左结点,1代表右结点。
比如要定位10号结点,先转为二进制为“1010”,定位顺序为:顶结点->左->右->左
此算法遍历的结节数为树的层数,正好为lgN对数级。
代码如下:

public Node seekNode(int x) {
						
		String s = Integer.toBinaryString(x);
		
		Node seek = top;		
		for(int i =1; i<s.length(); i++) {
			
			if(s.charAt(i)=='0') seek = seek.left;
			else seek = seek.right;
		}
		return seek;
		
	}

逻辑清晰,简单高效!

猜你喜欢

转载自blog.csdn.net/mikefbi/article/details/88870502