二叉树分层Z字形遍历
2016-12-20 00:00
399 查看
原题
Given a binary tree, return the zigzag level order traversal of its nodes’ values. (ie, from left to right, then right to left for the next level and alternate between).For example:
Given binary tree
{3,9,20,#,#,15,7},
3 / \ 9 20 / \ 15 7
return its zigzag level order traversal as:
[ [3], [20,9], [15,7] ]
题目大意
给定一棵二叉树,从顶向下,进行Z字形分层遍历,即:如果本层是从左向右的,下层就是从右向左。解题思路
二叉树分层遍历进行改进,使用两个栈来进行。代码实现
树结点类public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } }
算法实现类
import java.util.Deque; import java.util.LinkedList; import java.util.List; public class Solution { public List<List<Integer>> zigzagLevelOrder(TreeNode root) { List<List<Integer>> result = new LinkedList<>(); if (root == null) { return result; } // 遍历标志,0表示从左到右,1表示从右到左 int flag = 0; TreeNode node; // 记录每一层的元素 List<Integer> lay = new LinkedList<>(); // 双向队列,当作栈来使用,记录当前层待处理结点 Deque<TreeNode> stack = new LinkedList<>(); // 记录下一层待处理结点 Deque<TreeNode> nextStack = new LinkedList<>(); stack.add(root); while (!stack.isEmpty()) { // 删除栈顶元素 node = stack.removeLast(); // 结果入队 lay.add(node.val); // 如果当前是从左到右遍历,按左子树右子树的顺序添加 if (flag == 0) { if (node.left != null) { nextStack.addLast(node.left); } if (node.right != null) { nextStack.addLast(node.right); } } // 如果当前是从右到左遍历,按右子树左子树的顺序添加 else { if (node.right != null) { nextStack.addLast(node.right); } if (node.left != null) { nextStack.addLast(node.left); } } // 当前层已经处理完了 if (stack.isEmpty()) { Deque<TreeNode> temp = nextStack; nextStack = stack; stack = temp; // 标记下一层处理的方向 flag = 1 - flag; // 保存本层结果 result.add(lay); // 创建新的链表处理下一层的结果 lay = new LinkedList<>(); } } return result; } }
解题思路:
这题和第102题解法类似,对102题的方法进行改造,使用两个Deque来实现,第一个Deque()实现本层的遍历,第二个Deque()实现下层节点的输入。
二,AC了的程序(采用Java程序)
import java.util.*; class TreeNode{ int val; TreeNode left; TreeNode right; TreeNode(int x) { val=x; } } public class Test2 { List<List<Integer>> list=new ArrayList<List<Integer>>(); //leetcode 103 public List<List<Integer>> zigzagLevelOrder(TreeNode root) { if(root==null) { return list; } //LinkedList<TreeNode> queue=new LinkedList<TreeNode>(); //定义LinkedList类型 //queue.offer(root); // 首先把根节点入队列 boolean temp1=false; //temp1=false表示从左到右遍历,temp2=true表示从右到左遍历 Deque<TreeNode> queue=new LinkedList<TreeNode>();//Deque是双向队列,双向队列是指该队列两端的元素既能够入队,也能出队 Deque<TreeNode> nextqueue=new LinkedList<TreeNode>(); //记录下一层待处理结点 queue.add(root); //首先先把二叉树的根进入双端队列 List<Integer> templist=new LinkedList<Integer>(); //templist为临时的集; while(!queue.isEmpty()) //该双端队列不为空的 { TreeNode node=queue.removeLast();//删除 templist.add(node.val); //把节点值加入到临时集 if(temp1==false) //如果当前是从左到右遍历的,那么下一层要从左到右添加节点 { if(node.left!=null) { nextqueue.addLast(node.left); } if(node.right!=null) { nextqueue.addLast(node.right); } } else //当前是从右到左遍历的,那么下层就要从右到左添加节点的。 { if(node.right!=null) { nextqueue.addLast(node.right); } if(node.left!=null) { nextqueue.addLast(node.left); } } if(queue.isEmpty()) //如果当前这层已经变为空了 { Deque<TreeNode> temp=nextqueue; //就把下一层节点复制给当前节点,下一层的Deque边为空的 nextqueue=queue; //下一层deque变为空的。 queue=temp; temp1=(temp1==false)?true:false; list.add(templist); templist=new LinkedList<Integer>(); } } return list; } public static void main(String []args) { Test2 test=new Test2(); TreeNode root=new TreeNode(3); TreeNode p2=new TreeNode(9); TreeNode p3=new TreeNode(20); TreeNode p4=new TreeNode(15); TreeNode p5=new TreeNode(7); TreeNode p6=new TreeNode(4); TreeNode p7=new TreeNode(5); root.left=p2; root.right=p3; p3.left=p4; p3.right=p5; p5.left=p6; p5.right=p7; /* TreeNode root=new TreeNode(1); TreeNode p2=new TreeNode(2); TreeNode p3=new TreeNode(3); TreeNode p4=new TreeNode(4); TreeNode p5=new TreeNode(5); root.left=p2; root.right=p3; p2.left=p4; p3.right=p5; */ List<List<Integer>> list=test.zigzagLevelOrder(root); Iterator<List<Integer>> it1=list.iterator(); while(it1.hasNext()) { List<Integer> list2=it1.next(); Iterator<Integer> it2=list2.iterator(); while(it2.hasNext()) { int data=it2.next(); System.out.print(data+" "); } System.out.println(); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
运行结果:
相关文章推荐
- 【LeetCode-面试算法经典-Java实现】【103-Binary Tree Zigzag Level Order Traversal(二叉树分层Z字形遍历)】
- 3.10分层遍历二叉树-扩展问题
- 分层遍历二叉树
- 编程之美-分层遍历二叉树
- 从上往下打印二叉树(分层遍历)
- [编程之美] PSet3.10 分层遍历二叉树
- [二叉树的分层遍历] 倒序的树
- 分层遍历二叉树(按层次从上往下,从左往右)
- 编程之美。分层遍历二叉树(使用队列)
- 【遍历二叉树】06二叉树曲折(Z字形)层次遍历II【Binary Tree Zigzag Level Order Traversal】
- 编程之美读书笔记---分层遍历二叉树
- 二叉树的分层遍历
- 《编程之美》读书笔记16: 3.10 分层遍历二叉树
- flag10分层遍历二叉树
- 编程之美读书笔记3:3.10分层遍历二叉树
- [LeetCode] 103. Binary Tree Zigzag Level Order Traversal 二叉树的之字形层序遍历
- 分层遍历二叉树
- 分层遍历二叉树
- 二叉树的分层遍历
- 编程之美3.10 分层遍历二叉树