【数据结构与算法】王道考研数据结构与算法2022配套大题第四章(java语言描述)

5.2 二叉树的概念

5、最近公共节点
public static int 最近公共先祖(int x, int y) {
	if (x == 0 || y == 0) return 0;
	int flags;
	/* 計算出x和y具體在第幾層,原理類似於子網掩碼 */
	for (flags = 1; (x & flags) != x && (y & flags) != y; flags <<= 1, flags++);
	while ((x & flags) != x) x >>= 1;
	while ((y & flags) != y) y >>= 1;
	for (; x != y; x >>>= 1, y >>>= 1);
	return x;
}

  我感觉我写的这个算法效率是真的高。

  打脸来得真快,跟答案相比我这个就是个屎。如下:

public static int 最近公共先祖(int x, int y) {

	if (x <= 0 || y <= 0) {
		throw new IllegalArgumentException("傳參必須是正數!");
	}

	while (x != y) {
		if (x > y) {
			x >>>= 1;
		} else {
			y >>>= 1;
		}
	}

	return x;

}

线索二叉树与二叉树的遍历

  先写个二叉树:

class 二叉樹節點 {

	int;
	二叉樹節點 左;
	二叉樹節點 右;

	@Override
	public String toString() {
		return "" +;
	}

	public 二叉樹節點(int val) {
		this.= val;
	}

	public 二叉樹節點(int, 二叉樹節點 左, 二叉樹節點 右) {
		this.=;
		this.=;
		this.=;
	}

	public 二叉樹節點(Integer[] 數組) {
		int 指針 = 0;
		if (數組[0] == null) throw new IllegalArgumentException();
		this.= 數組[指針];
		Queue<二叉樹節點> 隊列 = new LinkedList<>();
		隊列.offer(this);
		while (!隊列.isEmpty()) {
			int 總數 = 隊列.size();
			while (總數 > 0) {
				二叉樹節點 節點 = 隊列.poll();
				總數--;
				指針++;
				if (指針 >= 數組.length) return;
				if (數組[指針] != null) {
					節點.= new 二叉樹節點(數組[指針]);
					隊列.add(節點.);
				}
				指針++;
				if (指針 >= 數組.length) return;
				if (數組[指針] != null) {
					節點.= new 二叉樹節點(數組[指針]);
					隊列.add(節點.);
				}
			}
		}
	}

}
3、用栈实现二叉树的后序遍历
public static String 後序遍歷(二叉樹節點 節點) {

	StringBuilder= new StringBuilder();
	Stack<二叉樹節點>= new Stack<>();
	二叉樹節點 前驅 = null;

	while (節點 != null || !.isEmpty()) {

		while(節點 != null) {.push(節點);
			節點 = 節點.;
		}

		節點 =.peek();

		if (節點.== null || 節點.== 前驅) {.append(節點.).append(' ');.pop();
			前驅 = 節點;
			節點 = null;
		} else {
			節點 = 節點.;
		}

	}

	return.toString();

}

  答案跟这个差不多。

4、自下而上、从右到左的层序遍历
public static String 自下而上從右到左層序遍歷(二叉樹節點 節點) {

	if (節點 == null) return "";

	StringBuilder= new StringBuilder();
	Stack<StringBuilder>= new Stack<>();
	Queue<二叉樹節點> 隊列 = new LinkedList<>();
	隊列.offer(節點);.push(new StringBuilder().append(節點.).append(' '));

	while (!隊列.isEmpty()) {

		StringBuilder 臨時串 = new StringBuilder();
		int 總數 = 隊列.size();

		while (總數 > 0) {

			二叉樹節點 臨時節點 = 隊列.poll();

			if (臨時節點.!= null) {
				臨時串.append(臨時節點.);
				隊列.offer(臨時節點.);
			}

			if (臨時節點.!= null) {
				臨時串.append(臨時節點.);
				隊列.offer(臨時節點.);
			}

			總數--;

		}

		if (臨時串.length() > 0) {.push(臨時串);
		}

	}

	while (!.isEmpty()) {.append(.pop()).append('\n');
	}

	return.toString();

}
5、非递归求二叉树高度

  坏得很啊,这非递归该咋写。

  麻麻的,我愣是写不出来。

  看了下答案上的提示,层序遍历,沃靠,豁然开朗,开写。

public static int 非遞歸求二叉樹高度(二叉樹節點 節點) {

	int 答案 = 0;
	Queue<二叉樹節點>= new LinkedList<>();.offer(節點);

	while (!.isEmpty()) {

		int 總數 =.size();
		答案++;

		while (總數 > 0) {

			二叉樹節點 臨時節點 =.poll();

			if (臨時節點.!= null) {.offer(臨時節點.);
			}

			if (臨時節點.!= null) {.offer(臨時節點.);
			}

			總數--;

		}

	}

	return 答案;

}
6、由先序遍历和中序遍历获得二叉树
private static int[] 先序;
private static int[] 中序;

public static 二叉樹節點 由先序中序獲得二叉樹(int[] 先序, int[] 中序) {
	if (先序.length != 中序.length) throw new IllegalArgumentException();
	if (先序.length == 0) return null;
	二叉樹節點.先序 = 先序;
	二叉樹節點.中序 = 中序;
	return 由先序中序獲得二叉樹(0, 先序.length, 0, 中序.length);
}

private static 二叉樹節點 由先序中序獲得二叉樹(int 先序始, int 先序長, int 中序始, int 中序長) {

	int= 先序[先序始];

	if (先序長 == 1 && 中序長 == 1) {
		if (先序[先序始] == 中序[中序始]) {
			return new 二叉樹節點();
		} else {
			throw new IllegalArgumentException();
		}
	}

	int 指針;
	boolean 找到否 = false;
	for (指針 = 0; 指針 < 中序長; 指針++) {
		if (== 中序[中序始 + 指針]) {
			找到否 = true;
			break;
		}
	}

	if (!找到否) throw new IllegalArgumentException();

	return new 二叉樹節點(,
			由先序中序獲得二叉樹(先序始 + 1, 指針, 中序始, 指針),
			由先序中序獲得二叉樹(先序始 + 1 + 指針, 先序長 - 1 - 指針, 中序始 + 指針 + 1, 中序長 - 1 - 指針));

}
7、判断是否为完全二叉树

  家人们,我哭了,你们呢 😭

  这就完全不会啊。

  首先呢,这玩意必然是层序,先写着看吧。

public static boolean 是完全二叉樹(二叉樹節點 節點) {
		
	if (節點 == null) return true;
	Queue<二叉樹節點>= new LinkedList<>();.offer(節點);
	
	while (!.isEmpty()) {
		
		boolean 旗幟 = false;
		int 總數 =.size();
		
		while (總數 > 0) {
			
			二叉樹節點 臨時節點 =.poll();
			
			if (臨時節點.!= null) {
				if (旗幟) return false;.offer(臨時節點.);
			} else {
				if (!旗幟) 旗幟 = true;
			}
		
			if (臨時節點.!= null) {
				if (旗幟) return false;.offer(臨時節點.);
			} else {
				if (!旗幟) 旗幟 = true;
			}
			
			總數--;
			
		}
		
	}

	return true;
	
}
8、分支节点个数
public static int 分支節點個數(二叉樹節點 節點) {
	if (節點 == null || (節點.== null && 節點.== null)) return 0;
	return 1 + 分支節點個數(節點.) + 分支節點個數(節點.);
}
9、交换左右子树节点
public static 二叉樹節點 交換左右子樹(二叉樹節點 節點) {

	if (節點 == null) return null;

	二叉樹節點 臨時節點 = 節點.;
	節點.= 交換左右子樹(節點.);
	節點.= 交換左右子樹(臨時節點);

	return 節點;

}

  后面这几个题简单的没亩。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九死九歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值