2021.2.7随笔
给出一颗二叉树,实现前序、中序、后序遍历
// 栈实现前序遍历
public List<E> preOrder() {
List<E> list = new ArrayList<>(); // 先创建一个容纳结果的 list 链表
// 创建一个栈用来遍历
LinkedList<Node> stack = new LinkedList<>();
// 根结点入栈
stack.push(root);
while (!stack.isEmpty()) { // 栈非空,遍历
Node pop = stack.pop(); // 从栈中取出元素,把元素放在 list 链表中
list.add(pop.value);
if (pop.right != null) stack.push(pop.right); // 右子树入栈,左子树入栈,因为后进先出
if (pop.left != null) stack.push(pop.left);
}
return list;
}
// 递归,实现前序遍历
public List<E> preOrder1() {
ArrayList<E> list = new ArrayList<>(); // 创建一个链表保存遍历结果
preOrder1(list, root);// 调用 preOrder1 方法,从根节点开始遍历
return list;
}
private void preOrder1(ArrayList<E> list, Node root) {
// TODO: 递归出口
if (root == null) return;
list.add(root.value); // 先遍历根结点
preOrder1(list, root.left); // 遍历左子树
preOrder1(list, root.right); // 遍历右子树
}
// 栈,实现中序遍历
public List<E> inOrder() {
List<E> list = new ArrayList<>(); // 创建一个链表容纳遍历后的结果
LinkedList<Node> stack = new LinkedList<>(); // 创建一个辅助栈
Node target = root; // 标记根结点
while (!stack.isEmpty() || target != null) { // 栈非空 或者 标记点不为 null 就进行循环遍历
while (target != null) { // 如果标记点不为 null 先把标记点入栈,去找他的左子树,直到找到
stack.push(target);
target = target.left;
}
Node pop = stack.pop(); // 出栈操作,并记录出栈结点
list.add(pop.value); // 将栈顶元素放在链表中
target = pop.right; // 让标记结点, 指向出栈结点的right结点
}
return list;
}
// 递归,实现中序遍历
public List<E> inOrder1() {
ArrayList<E> list = new ArrayList<>();
inOrader1(list, root);
return list;
}
private void inOrader1(ArrayList<E> list, Node root) {
// TODO: 递归出口
if (root == null) return;
inOrader1(list, root.left);
list.add(root.value);
inOrader1(list, root.right);
}
// 栈,实现后序遍历
public List<E> postOrder() {
List<E> list = new ArrayList<>(); // 创建一个链表容纳遍历后的结果(头插法)
LinkedList<Node> stack = new LinkedList<>(); // 创建一个辅助栈
stack.push(root); // 根节点最先入栈
while (!stack.isEmpty()) { // 栈非空就循环遍历
Node pop = stack.pop(); // 标记栈顶元素,并出栈
list.add(0, pop.value); // 利用头插法,在链表下标为 0 的位置插入出栈元素
if (pop.left != null) stack.push(pop.left); // 遍历左右子树,先左后右添加入栈
if (pop.right != null) stack.push(pop.right);
}
return list;
}
// 递归,实现后序遍历
public List<E> posrOrder1() {
ArrayList<E> list = new ArrayList<>();
posrOrder1(list, root);
return list;
}
private void posrOrder1(ArrayList<E> list, Node root) {
// TODO:递归出口
if (root == null) return;
posrOrder1(list, root.left);
posrOrder1(list, root.right);
list.add(root.value);
}
// 层级遍历,广度遍历,广度优先搜索遍历 (用队列实现)
public List<E> levOrder() {
ArrayList<E> list = new ArrayList<>(); // 创建一个集合保存遍历的结果
LinkedList<Node> queue = new LinkedList<>(); // 创建一个队列进行遍历
queue.offer(root); // 根节点入队
while (!queue.isEmpty()) { // 循环遍历
Node poll = queue.poll(); // 出队一个元素,并遍历
list.add(poll.value);
if (poll.left != null) queue.offer(poll.left); // 左右子树入队列
if (poll.right != null) queue.offer(poll.right);
}
return list;
}