直观理解数据结构的网站:https://visualgo.net/zh
树的基本操作
递归加入元素到二分查找树
二叉树的最小深度和最大深度
递归方法
// 使用BFS不会遍历所有节点
int minDepth(TreeNode* root) {
if(root == NULL)
return 0;
// 不为空的根节点深度为1 : <root, 1>
queue<pair<TreeNode*, int>> queue;
queue.push(make_pair(root, 1));
while(!queue.empty()){
TreeNode* cur = queue.front().first;
int step = queue.front().second;
queue.pop();
// 如果cur为叶子节点
if(!cur->left && !cur->right)
return step;
else{
if(cur->left)
queue.push(make_pair(cur->left, step + 1));
if(cur->right)
queue.push(make_pair(cur->right, step + 1));
}
}
assert(false);
return -1;
}
搜索
广度优先搜索
102 层序遍历
103 之字形层序遍历
199 二叉树的右视图
下列代码是之字形遍历,当从左往右遍历,levelList从队尾入队,队首出队;当从右往左遍历,levelList从队首入队,队首出队,相当于栈,达到之字形遍历的效果。 比较tricky的地方是通过加入null隔离层与层,好好思考一下什么时机加入null比较好。
层序遍历、右视图、左视图都可以通过如下代码修改,大家思考一下吧。
// leetcode 103 之字形遍历
List<List<Integer>> zigzagLevelOrder(TreeNode root){
List<List<Integer>> res = new ArrayList<>();
if(root ==null){
return res;
}
LinkedList<Integer> levelList = new LinkedList<>();
LinkedList<TreeNode> nodeQueue = new LinkedList<>();
boolean fromLeft = true;
nodeQueue.add(root);
nodeQueue.add(null); // tricky 隔离层与层
while(!nodeQueue.isEmpty()){
TreeNode cur = nodeQueue.poll();
if(cur!=null){
if(fromLeft)
levelList.addLast(cur.val);
else
levelList.addFirst(cur.val);
if(cur.left!=null){
nodeQueue.add(cur.left);
}
if(cur.right!=null){
nodeQueue.add(cur.right);
}
}else{
res.add(levelList);
levelList = new LinkedList<>();
fromLeft = !fromLeft;
if(nodeQueue.size()>0) // 注意此处的条件,当队列为空,说明已经遍历完成
nodeQueue.add(null);
}
}
return res;
}
层序遍历也可以一次取出所有当前层的节点,如下代码所示:
List<List<Integer>> levelOrder(TreeNode root){
List<List<Integer>> levels = new ArrayList<List<Integer>>();
if(root==null) return levels;
LinkedList<TreeNode> q = new LinkedList<>();
q.add(root);
int level = 0;
while (!q.isEmpty()) {
levels.add(new ArrayList<Integer>());
int size = q.size();
for (int i = 0; i < size; i++) { // 每一次将整个一层的节点全部处理
TreeNode n = q.poll();
levels.get(level).add(n.val);
if(n.left!=null) q.add(n.left);
if(n.right!=null) q.add(n.right);
}
level++;
}
return levels;
}