您的位置:首页 > 其它

二叉树--遍历

2016-05-23 19:52 288 查看

三种遍历方式

遍历分为非递归和递归两种形式,递归的遍历很简单,本文主要针对非递归算法进行说明,详细代码如下:

static void visit(TreeNode root) {
System.out.println(root.key + "----------->" + root.value);
}
//先序遍历
static void preOrder(TreeNode root) {
if (root != null) {
visit(root);
preOrder(root.left);
preOrder(root.right);
}
}

public static void preOrderImpl01(TreeNode node) {
if (node == null)
return;

LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
stack.push(node);

while (!stack.isEmpty()) {
TreeNode temp = stack.pop();
visit(temp);
if (temp.right != null)
stack.push(temp.right);
if (temp.left != null)
stack.push(temp.left);
}
}


非递归解释:采用栈,先压入根节点,接着出栈,压入右节点,左节点,下一次左节点出栈,压入左节点的左右节点,西安便利左子树,再遍历右子树,输出的顺序为先序遍历中–>左–>右

//中序遍历
static void inOrder(TreeNode root) {
if (root != null) {
midOrder(root.left);
visit(root);
midOrder(root.right);
}
}

static void inOrder(TreeNode root) {
LinkedList<TreeNode> stack = new LinkedList<BinaryTree.TreeNode>();
TreeNode node = root;
while (node != null || !stack.isEmpty()) {
while (node != null) {
stack.push(node);
node = node.left;
}

node = stack.pop();
visit(node);
node = node.right;
if (node != null) {
stack.push(node);
node = node.left;
}
}

}


非递归解释:采用栈,先压入根节点,接着依次压入左节点,下一次左节点出栈,如果该点有右子树,则右节点进栈,节点右节点的左节点,这样进行下一次循环时,就可以进行while的左子树压栈,保证左子树有限进栈;如果该点无右子树,则node赋值为空,可以保证不进入上面while的循环。先便利左子树,再遍历右子树,输出的顺序为先序遍历左–>中–>右

//后序遍历
static void postOrder(TreeNode root) {
if (root != null) {
postOrder(root.left);
postOrder(root.right);
visit(root);
}
}

public static void postOrder(TreeNode node) {
if (node == null)
return;

LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
stack.push(node);

while (!stack.isEmpty()) {
TreeNode curr = stack.peek();
if (!curr.flag) {
if (curr.right != null) {
stack.push(curr.right);
}
if (curr.left != null) {
System.out.println(curr.left.value);
stack.push(curr.left);
}
curr.flag = true;
}

TreeNode temp = stack.peek();
if (temp.flag == true) {
visit(stack.pop());
}
}

}

//不使用标记flag的方法
public List<Integer> postorderTraversal(TreeNode root) {
Deque<TreeNode> stack = new LinkedList<>();
stack.push(root);
List<Integer> ret = new ArrayList<>();
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
if (node != null) {
ret.add(node.val);
stack.push(node.left);
stack.push(node.right);
}
}
Collections.reverse(ret);
return ret;
}


非递归解释:这个里边增加了节点访问标记,采用栈,先压入根节点,接着压入右节点,左节点,然后取栈顶元素,看是否符合输出条件(不到左子树的最作边节点,就不符合输出条件),直到最左边的一个中–>右–>左结构压栈,下一次进行出栈,则是左,右,中,如果右节点上还有子树,进入上面的if,再进行先前的操作,这样左子树就遍历完成,接着会遍历右子树,最后返回根节点,输出的顺序为先序遍历左–>右–>中

树的结构如下:

public static class TreeNode {
int key;
Object value;
boolean flag;
TreeNode left;
TreeNode right;

TreeNode(int key, Object value) {
this.value = value;
this.key = key;
}
}


层次遍历

public List<List<Integer>> levelOrder(TreeNode root) {

List<List<Integer>> list = new LinkedList<>();
if (root == null)
return list;
List<TreeNode> nodeList = new ArrayList<>();
TreeNode node = root;
nodeList.add(node);

int len = 1;
int count = 0;
while (count < len) {
List<Integer> valueList = new LinkedList<>();
while (count < len) {
TreeNode nodeTemp = nodeList.get(count);
valueList.add(nodeTemp.val);
if (nodeTemp.left != null) {
nodeList.add(nodeTemp.left);
}

if (nodeTemp.right != null) {
nodeList.add(nodeTemp.right);
}
count++;
}

len = nodeList.size();
list.add(valueList);
}

return list;
}


这个代码比较简单,博主自己实现的,所以代码看着比较乱一点,同时也可以采用队列的结构,来实现层次遍历。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: