思路:
方法一
1、使用先序遍历每个节点 放入集合中,然后遍历集合,左子树为null,右子树为下一个节点。代码如下:
public void flatten(TreeNode root) {if (root==null){return;}LinkedList<TreeNode> list = new LinkedList<>();process(root, list); // 填充链表TreeNode cur = list.get(0); // 从第一个节点开始for (int i = 1; i < list.size(); i++) {cur.left = null; // 确保左子树为 nullcur.right = list.get(i); // 将当前节点的右指针指向链表中的下一个节点cur = cur.right; // 移动到下一个节点}}private void process(TreeNode root, LinkedList<TreeNode> list) {if (root==null){return;}list.add(root);process(root.left,list);process(root.right,list);}
方法二
- 将左子树插入到右子树的地方
- 将原来的右子树接到左子树的最右边节点
- 考虑新的右子树的根节点,一直重复上边的过程,直到新的右子树为 null
public void flatten(TreeNode root) {while (root != null) { //左子树为 null,直接考虑下一个节点if (root.left == null) {root = root.right;} else {// 找左子树最右边的节点TreeNode pre = root.left;while (pre.right != null) {pre = pre.right;} //将原来的右子树接到左子树的最右边节点pre.right = root.right;// 将左子树插入到右子树的地方root.right = root.left;root.left = null;// 考虑下一个节点root = root.right;}}
}
方法三:Morris遍历
public static void flatten(TreeNode root) {if (root == null) {return;}TreeNode pre = null;TreeNode cur = root;TreeNode mostRight = null;while (cur != null) {mostRight = cur.left;if (mostRight != null) {while (mostRight.right != null && mostRight.right != cur) {mostRight = mostRight.right;}if (mostRight.right == null) {mostRight.right = cur;if (pre != null) {pre.left = cur;}pre = cur;cur = cur.left;continue;} else {mostRight.right = null;}} else {if (pre != null) {pre.left = cur;}pre = cur;}cur = cur.right;}cur = root;TreeNode next = null;while (cur != null) {next = cur.left;cur.left = null;cur.right = next;cur = next;}}