栈队列链表二叉树

栈和队列

1. 栈的实现

 1 import java.util.EmptyStackException;
 2 
 3 //基于数组实现的栈
 4 public class ArrayStack {
 5     private int[] arr;
 6     private int top;
 7 
 8     ArrayStack(int initialSize){
 9         if(initialSize<=0)
10             throw new RuntimeException("非法初始化参数:"+initialSize);
11         top=-1;
12         arr=new int[initialSize];
13     }
14 
15     public int push(int x){
16         if(top==arr.length-1)
17             throw new StackOverflowError();
18         arr[++top]=x;
19         return x;
20     }
21 
22     public int pop(){
23         if(top<0)
24             throw new EmptyStackException();
25         return arr[top--];
26     }
27 
28     public int peek(){
29         if(top<0)
30             throw new EmptyStackException();
31         return arr[top];
32     }
33 
34     public boolean isEmpty(){
35         return top==-1;
36     }
37 
38 }
 1 import java.util.EmptyStackException;
 2 import java.util.LinkedList;
 3 
 4 //基于链表实现栈
 5 public class ListStack {
 6     private LinkedList<Integer> list=new LinkedList<>();
 7 
 8     public int push(int x){
 9         list.addLast(x);
10         return x;
11     }
12 
13     public int pop(){
14         if(list.size()<=0)
15             throw new EmptyStackException();
16         return list.removeLast();
17     }
18 
19     public int peek(){
20         if(list.size()<=0)
21             throw new EmptyStackException();
22         return list.getLast();
23     }
24 
25     public boolean isEmpty(){
26         return list.size()==0;
27     }
28     
29 }

2. 队列实现

 1 /**
 2  * 顺序队列的假溢出
 3  * 改进为循环队列
 4  * head指向队列的第一个元素
 5  * tail指向队尾的下一个位置
 6  * 实际存储的元素数为len-1(区分队列空和队列满的情况)
 7  */
 8 public class ArrayQueue {
 9     private int[] arr;
10     private int head;
11     private int tail;
12     private int len;
13 
14     ArrayQueue(int len){
15         this.len = len;
16         arr = new int[len];
17     }
18 
19     public int offer(int x){
20         if((tail+1)%len==head){
21             throw new RuntimeException("circle queue is Full");
22         }else {
23             arr[tail]=x;
24             tail=(tail+1)%len;
25             return x;
26         }
27     }
28 
29     public int poll(){
30         if(head==tail){
31             throw new RuntimeException("circle queue is Null");
32         }else{
33             int n=arr[head];
34             head=(head+1)%len;
35             return n;
36         }
37     }
38 
39 }
 1 import java.util.LinkedList;
 2 import java.util.Queue;
 3 
 4 public class ListQueue {
 5     private Queue<Integer> queue=new LinkedList<>();
 6 
 7     public int peek(){
 8         return queue.peek();
 9     }
10 
11     public boolean offer(int x){
12         return queue.offer(x);
13     }
14 
15     public int poll(){
16         return queue.poll();
17     }
18 
19     public boolean isEmpty() {
20         return queue.isEmpty();
21     }
22 
23 }

3. 两个栈实现一个队列

 1 import java.util.Stack;
 2 
 3 public class MyQueue {
 4     private Stack<Integer> stack=new Stack<>();
 5     private Stack<Integer> out=new Stack<>();
 6 
 7     public int offer(int x){
 8         stack.push(x);
 9         return x;
10     }
11 
12     public int poll(){
13         if(out.isEmpty())
14             while(!stack.isEmpty())
15                 out.push(stack.pop());
16         
17         if(out.isEmpty())
18             throw new RuntimeException("队列为空!");
19         return out.pop();
20     }
21     
22 }

4. 两个队列实现一个栈

 1 import java.util.EmptyStackException;
 2 import java.util.LinkedList;
 3 import java.util.Queue;
 4 
 5 public class MyStack {
 6     private Queue<Integer> queue=new LinkedList<>();
 7     private Queue<Integer> queue2=new LinkedList<>();
 8 
 9     public int push(int x){
10         if(!queue.isEmpty())
11             queue.offer(x);
12         else
13             queue2.offer(x);
14         return x;
15     }
16 
17     public int pop(){
18         if(queue.isEmpty()&&queue2.isEmpty())
19             throw new EmptyStackException();
20         if(queue.isEmpty()){
21             while(queue2.size()>1)
22                 queue.offer(queue2.poll());
23             return queue2.poll();
24         }else{
25             while(queue.size()>1)
26                 queue2.offer(queue.poll());
27             return queue.poll();
28         }
29     }
30     
31 }

5. 设计含最小函数min的栈

 1 import java.util.Stack;
 2 
 3 public class MinStack {
 4     Stack<Integer> stack;
 5     Stack<Integer> stackMin;
 6 
 7     public MinStack() {
 8         this.stack=new Stack<>();
 9         this.stackMin=new Stack<>();
10     }
11 
12     public void push(int x) {
13         stack.push(x);
14         if(stackMin.isEmpty())
15             stackMin.push(x);
16         else if(stackMin.peek()<x)
17             stackMin.push(stackMin.peek());
18         else
19             stackMin.push(x);
20     }
21 
22     public void pop() {
23         if(!stack.isEmpty()&&!stackMin.isEmpty()){
24             stack.pop();
25             stackMin.pop();
26         }else{
27             System.out.println("栈已经没有元素了...");
28         }
29     }
30 
31     public int top() {
32         return stack.peek();
33     }
34 
35     public int getMin() {
36         return stackMin.peek();
37     }
38 }

6. 判断出栈序列是否合法

 1 import java.util.Stack;
 2 
 3 public class Main {
 4     public static boolean IsPopOrder(int [] pushA,int [] popA) {
 5         Stack<Integer> stack = new Stack<>();
 6         int popIndex = 0;
 7         for(int i = 0; i< pushA.length;i++){
 8             stack.push(pushA[i]);
 9             while(!stack.empty() &&stack.peek() == popA[popIndex]){
10                 stack.pop();
11                 popIndex++;
12             }
13         }
14         return stack.empty();
15     }
16     
17 }

链表

  1 import java.util.HashSet;
  2 import java.util.Stack;
  3 
  4 public class List {
  5     static class Node{
  6         int val;
  7         Node next;
  8 
  9         public Node(int val){
 10             this.val=val;
 11         }
 12     }
 13 
 14     //创建链表
 15     public Node head;
 16     public Node current;
 17     public void add(int val){
 18         if(head==null){
 19             head=new Node(val);
 20             current=head;
 21         }else {
 22             current.next=new Node(val);
 23             current=current.next;
 24         }
 25     }
 26 
 27     //遍历输出链表
 28     public static void print(Node head){
 29         if(head==null)
 30             return;
 31         Node cur=head;
 32         while(cur.next!=null){
 33             System.out.print(cur.val+"->");
 34             cur=cur.next;
 35         }
 36         System.out.println(cur.val);
 37     }
 38 
 39     //获取链表节点数
 40     public static int getLength(Node head){
 41         if(head==null)
 42             return 0;
 43         int count=0;
 44         Node cur=head;
 45         while(cur!=null){
 46             count++;
 47             cur=cur.next;
 48         }
 49         return count;
 50     }
 51 
 52     //查找倒数第k个节点
 53     public static int findLastNode(Node head,int k){
 54         if(k==0||head==null)
 55             return -1;
 56         int size=getLength(head);
 57         if(k>size)
 58             return -1;
 59         Node cur=head;
 60         for(int i=0;i<size-k;i++){
 61             cur=cur.next;
 62         }
 63         return cur.val;
 64     }
 65     //在不允许遍历链表长度的情况下查找倒数第k个节点
 66     public static int findLastNode2(Node head,int k){
 67         if(k==0||head==null)
 68             return -1;
 69         Node fast=head,slow=head;
 70         for(int i=0;i<k-1;i++){
 71             fast=fast.next;
 72             if(fast==null)
 73                 return -1;
 74         }
 75         while(fast.next!=null){
 76             slow=slow.next;
 77             fast=fast.next;
 78         }
 79         return slow.val;
 80     }
 81 
 82     //查找中间节点
 83     public static int findMidNode(Node head){
 84         if(head==null)
 85             return -1;
 86         Node fast=head,slow=head;
 87         while(fast!=null&&fast.next!=null){
 88             slow=slow.next;
 89             fast=fast.next.next;
 90         }
 91         return slow.val;
 92     }
 93 
 94     //合并两个有序链表
 95     public static Node mergeTwoLists(Node l1,Node l2){
 96         if(l1==null)
 97             return l2;
 98         if(l2==null)
 99             return l1;
100         if(l1.val<l2.val){
101             l1.next=mergeTwoLists(l1.next,l2);
102             return l1;
103         }else {
104             l2.next=mergeTwoLists(l1,l2.next);
105             return l2;
106         }
107     }
108 
109     //循环翻转
110     public static Node reverseListByLoop(Node head){
111         Node pre=null;
112         Node next=null;
113         while(head!=null){
114             next=head.next;
115             head.next=pre;
116             pre=head;
117             head=next;
118         }
119         return pre;
120     }
121     //递归翻转
122     public static Node reverseListByRecursion(Node head){
123         if(head==null||head.next==null)
124             return head;
125         Node pre=reverseListByRecursion(head.next);
126         head.next.next=head;
127         head.next=null;
128         return pre;
129     }
130 
131     //反向打印链表
132     public static void reversePrint(Node head){
133         if(head==null)
134             return;
135         Stack<Node> stack=new Stack<>();
136         Node cur=head;
137         while(cur!=null){
138             stack.push(cur);
139             cur=cur.next;
140         }
141         while(!stack.isEmpty()){
142             System.out.print(stack.pop().val+" ");
143         }
144         System.out.println();
145     }
146 
147     //判断单链表是否有环
148     public static Node hasCycle(Node head){
149         if(head==null)
150             return null;
151         Node fast=head,slow=head;
152         while(fast!=null&&fast.next!=null){
153             slow=slow.next;
154             fast=fast.next.next;
155             if(slow==fast)
156                 return slow;
157         }
158         return null;
159     }
160 
161     //创建有环链表
162     public void add(Node node){
163         if(node==null)
164             return;
165         if(head==null){
166             head=node;
167             current=head;
168         }else {
169             current.next=node;
170             current=current.next;
171         }
172     }
173     //获取有环链表环的长度
174     public static int getCycleLength(Node node){
175         Node cur=node;
176         int length=0;
177         while(cur!=null){
178             cur=cur.next;
179             length++;
180             if(cur==node)
181                 return length;
182         }
183         return length;
184     }
185 
186     //获取环的起点
187     public static Node getCycleStart(Node head){
188         if(head==null)
189             return null;
190         Node fast=head,slow=head;
191         while(fast!=null&&fast.next!=null){
192             slow=slow.next;
193             fast=fast.next.next;
194             if(slow==fast){
195                 fast=head;
196                 /*
197                 假设链表起点到环的起点为x
198                 链表起点到快慢指针相遇节点为x+z
199                 环的长度为y
200                 那么有2(x+z)-(x+z)=k*y
201                 即x=k*y-z=y-z+(k-1)*y
202                  */
203                 while(slow!=fast){
204                     slow=slow.next;
205                     fast=fast.next;
206                 }
207                 return slow;
208             }
209         }
210         return null;
211     }
212     //获取环的起点2
213     public static Node getCycleStart2(Node head){
214         HashSet<Node> set=new HashSet<>();
215         while(head!=null){
216             if(!set.add(head))
217                 return head;
218             head=head.next;
219         }
220         return null;
221     }
222 
223     /*
224     获取两个单链表相交的第一个节点
225     1.压入栈中,依次比较找出最后一个相同的节点,时间空间复杂度均为O(len1+len2)
226     2.快慢指针
227      */
228     public static Node getFirstCommonNode(Node l1,Node l2){
229         if(l1==null||l2==null)
230             return null;
231         int len1=getLength(l1);
232         int len2=getLength(l2);
233         Node longHead=len1>len2?l1:l2,shortHead=len1>len2?l2:l1;
234 
235         for(int i=0;i<Math.abs(len1-len2);i++) longHead=longHead.next;
236         while(longHead!=null&&shortHead!=null){
237             if(longHead==shortHead)
238                 return longHead;
239             longHead=longHead.next;
240             shortHead=shortHead.next;
241         }
242         return null;
243     }
244 
245 }

 二叉树

  1 import java.util.*;
  2 
  3 class TreeNode{
  4     int val;
  5     TreeNode left;
  6     TreeNode right;
  7 
  8     public TreeNode(int val){
  9         this.val=val;
 10     }
 11 }
 12 
 13 public class Tree {
 14     //递归求二叉树节点个数
 15     public static int getNodeNumByRecursion(TreeNode root){
 16         if(root==null)
 17             return 0;
 18         return getNodeNumByRecursion(root.left)+getNodeNumByRecursion(root.right)+1;
 19     }
 20     //迭代求二叉树节点个数
 21     public static int getNodeNumByLoop(TreeNode root){
 22         if(root==null)
 23             return 0;
 24         int count=1;
 25         Queue<TreeNode> queue=new LinkedList<>();
 26         queue.add(root);
 27 
 28         while(!queue.isEmpty()){
 29             TreeNode cur=queue.remove();
 30             if(cur.left!=null){
 31                 queue.add(cur.left);
 32                 count++;
 33             }
 34             if(cur.right!=null){
 35                 queue.add(cur.right);
 36                 count++;
 37             }
 38         }
 39         return count;
 40     }
 41 
 42     //递归求二叉树的深度
 43     public static int getDepthByRecursion(TreeNode root){
 44         if(root==null)
 45             return 0;
 46         return Math.max(getDepthByRecursion(root.left),getDepthByRecursion(root.right))+1;
 47     }
 48     //迭代求二叉树的深度
 49     public static int getDepthByLoop(TreeNode root){
 50         if(root==null)
 51             return 0;
 52         int depth=0;
 53         int currentLevelNodes=1;
 54         int nextLevelNodes=0;
 55         Queue<TreeNode> queue=new LinkedList<>();
 56         queue.add(root);
 57 
 58         while(!queue.isEmpty()){
 59             TreeNode cur=queue.remove();
 60             currentLevelNodes--;
 61             if(cur.left!=null){
 62                 queue.add(cur.left);
 63                 nextLevelNodes++;
 64             }
 65             if(cur.right!=null){
 66                 queue.add(cur.right);
 67                 nextLevelNodes++;
 68             }
 69             if(currentLevelNodes==0){
 70                 depth++;
 71                 currentLevelNodes=nextLevelNodes;
 72                 nextLevelNodes=0;
 73             }
 74         }
 75         return depth;
 76     }
 77 
 78     //递归前序遍历
 79     public static void preorderTraversalByRecursion(TreeNode root){
 80         if(root==null)
 81             return;
 82         System.out.print(root.val+" ");
 83         preorderTraversalByRecursion(root.left);
 84         preorderTraversalByRecursion(root.right);
 85     }
 86     //迭代前序遍历
 87     public static void preorderTraversalByLoop(TreeNode root){
 88         if(root==null)
 89             return;
 90         Stack<TreeNode> stack=new Stack<>();
 91         stack.push(root);
 92 
 93         while(!stack.isEmpty()){
 94             TreeNode cur=stack.pop();
 95             System.out.print(cur.val+" ");
 96             if(cur.right!=null)
 97                 stack.push(cur.right);
 98             if(cur.left!=null)
 99                 stack.push(cur.left);
100         }
101     }
102 
103     //递归中序遍历
104     public static void inorderTraversalByRecursion(TreeNode root){
105         if(root==null)
106             return;
107         inorderTraversalByRecursion(root.left);
108         System.out.print(root.val+" ");
109         inorderTraversalByRecursion(root.right);
110     }
111     //迭代中序遍历
112     //todo
113     public static void inorderTraversalByLoop(TreeNode root){
114         if(root==null)
115             return;
116         Stack<TreeNode> stack=new Stack<>();
117         TreeNode cur=root;
118 
119         while(true){
120             while(cur!=null){
121                 stack.push(cur);
122                 cur=cur.left;
123             }
124             if(stack.isEmpty())
125                 break;
126             cur=stack.pop();
127             System.out.print(cur.val+" ");
128             cur=cur.right;
129         }
130     }
131 
132     //递归后序遍历
133     public static void postorderTraversalByRecursion(TreeNode root){
134         if(root==null)
135             return;
136         postorderTraversalByRecursion(root.left);
137         postorderTraversalByRecursion(root.right);
138         System.out.print(root.val+" ");
139     }
140     //迭代后序遍历
141     //todo
142     public static void postorderTraversalByLoop(TreeNode root){
143         if(root==null)
144             return;
145         Stack<TreeNode> stack=new Stack<>();
146         Stack<TreeNode> output=new Stack<>();
147         stack.push(root);
148 
149         while(!stack.isEmpty()){
150             TreeNode cur=stack.pop();
151             output.push(cur);
152             if(cur.left!=null)
153                 stack.push(cur.left);
154             if(cur.right!=null)
155                 stack.push(cur.right);
156         }
157         while(!output.isEmpty()) System.out.print(output.pop().val+" ");
158     }
159 
160     //递归分层遍历二叉树
161     //todo
162     public static void levelTraversalByRecursion(TreeNode root){
163         ArrayList<ArrayList<Integer>> res=new ArrayList<>();
164         dfs(root,0,res);
165         System.out.print(res);
166 
167     }
168     private static void dfs(TreeNode root,int level,ArrayList<ArrayList<Integer>> res){
169         if(root==null)
170             return;
171         if(level>=res.size())
172             res.add(new ArrayList<>());
173         res.get(level).add(root.val);
174         dfs(root.left,level+1,res);
175         dfs(root.right,level+1,res);
176     }
177     //迭代分层遍历二叉树
178     public static void levelTraversalByLoop(TreeNode root){
179         if (root == null)
180             return;
181         LinkedList<TreeNode> queue = new LinkedList<>();
182         queue.push(root);
183 
184         while (!queue.isEmpty()) {
185             TreeNode cur = queue.removeFirst();
186             System.out.print(cur.val + " ");
187             if (cur.left != null) queue.add(cur.left);
188             if (cur.right != null) queue.add(cur.right);
189         }
190     }
191 
192     //递归 二叉查找树转为有序的双向链表 仅仅调节指针
193     //todo 需要仔细琢磨
194     public static TreeNode convertBST2DLLByRecursion(TreeNode root){
195         root=convertBST2DLL(root);
196         while(root.left!=null)
197             root=root.left;
198         return root;
199     }
200     private static TreeNode convertBST2DLL(TreeNode root){
201         if(root==null||(root.left==null&&root.right==null))
202             return root;
203         TreeNode cur=null;
204         if(root.left!=null){
205             cur=convertBST2DLL(root.left);
206             while(cur.right!=null)
207                 cur=cur.right;
208             cur.right=root;
209             root.left=cur;
210         }
211         if(root.right!=null){
212             cur=convertBST2DLL(root.right);
213             while(cur.left!=null)
214                 cur=cur.left;
215             cur.left=root;
216             root.right=cur;
217         }
218         return root;
219     }
220     //迭代 二叉查找树转为有序的双向链表 仅仅调节指针
221     //todo
222     public static TreeNode convertBST2DLLByLoop(TreeNode root){
223         if(root==null)
224             return null;
225         TreeNode head=null,cur=root,pre=null;
226         Stack<TreeNode> stack=new Stack<>();
227 
228         while(!stack.isEmpty()||cur!=null){
229             while(cur!=null){
230                 stack.push(cur);
231                 cur=cur.left;
232             }
233             if(!stack.isEmpty()){
234                 cur=stack.pop();
235                 if(head==null)
236                     head=cur;
237                 if(pre!=null){
238                     pre.right=cur;
239                     cur.left=pre;
240                 }
241                 pre=cur;
242                 cur=cur.right;
243             }
244         }
245         return head;
246     }
247 
248     //递归求二叉树的第k层的节点个数
249     public static int getNodeNumKthLevelByRecursion(TreeNode root,int k){
250         if(root==null||k<1)
251             return 0;
252         if(k==1)
253             return 1;
254         return getNodeNumKthLevelByRecursion(root.left,k-1)+getNodeNumKthLevelByRecursion(root.right,k-1);
255     }
256     //迭代求二叉树的第k层的节点个数
257     public static int getNodeNumKthLevelByLoop(TreeNode root,int k){
258         if(root==null)
259             return 0;
260         Queue<TreeNode> queue=new LinkedList<>();
261         queue.add(root);
262 
263         int i=1;
264         int currentLevelNodes=1;
265         int nextLevelNodes=0;
266 
267         while(!queue.isEmpty()&&i<k){
268             TreeNode cur=queue.remove();
269             currentLevelNodes--;
270             if(cur.left!=null){
271                 queue.add(cur.left);
272                 nextLevelNodes++;
273             }
274             if(cur.right!=null){
275                 queue.add(cur.right);
276                 nextLevelNodes++;
277             }
278             if(currentLevelNodes==0){
279                 currentLevelNodes=nextLevelNodes;
280                 nextLevelNodes=0;
281                 i++;
282             }
283         }
284         return currentLevelNodes;
285     }
286 
287     //递归求二叉树的叶子节点个数
288     public static int getNodeNumLeafByRecursion(TreeNode root){
289         if(root==null)
290             return 0;
291         if(root.left==null&&root.right==null)
292             return 1;
293         return getNodeNumLeafByRecursion(root.left)+getNodeNumLeafByRecursion(root.right);
294     }
295     //迭代求二叉树的叶子节点个数 基于Level order traversal
296     public static int getNodeNumLeafByLoop(TreeNode root){
297         if(root==null)
298             return 0;
299         Queue<TreeNode> queue=new LinkedList<>();
300         queue.add(root);
301 
302         int leafNodes=0;
303         while(!queue.isEmpty()){
304             TreeNode cur=queue.remove();
305             if(cur.left!=null)
306                 queue.add(cur.left);
307             if(cur.right!=null)
308                 queue.add(cur.right);
309             if(cur.left==null&&cur.right==null)
310                 leafNodes++;
311         }
312         return leafNodes;
313     }
314 
315     //递归判断两个二叉树是否一样
316     public static boolean isSameTreeByRecursion(TreeNode r1,TreeNode r2){
317         if(r1==null&&r2==null)
318             return true;
319         if(r1==null||r2==null)
320             return false;
321         if(r1.val!=r2.val)
322             return false;
323         return isSameTreeByRecursion(r1.left,r2.left)&&isSameTreeByRecursion(r1.right,r2.right);
324     }
325     //迭代判断两个二叉树是否一样
326     public static boolean isSameTreeByLoop(TreeNode r1,TreeNode r2){
327         if(r1==null&&r2==null)
328             return true;
329         if(r1==null||r2==null)
330             return false;
331         Stack<TreeNode> stack1=new Stack<>();
332         Stack<TreeNode> stack2=new Stack<>();
333         stack1.push(r1);
334         stack2.push(r2);
335 
336         while(!stack1.isEmpty()&&!stack2.isEmpty()){
337             TreeNode n1=stack1.pop();
338             TreeNode n2=stack2.pop();
339             if(n1==null&&n2==null)
340                 continue;
341             else if(n1!=null&&n2!=null&&n1.val==n2.val){
342                 stack1.push(n1.right);
343                 stack1.push(n1.left);
344                 stack2.push(n2.right);
345                 stack2.push(n2.left);
346             }
347             else
348                 return false;
349         }
350         return true;
351     }
352 
353     //递归判断二叉树是否为平衡二叉树
354     public static boolean isAVLByRecursion(TreeNode root){
355         if(root==null)
356             return true;
357         if(Math.abs(getDepthByRecursion(root.left)-getDepthByRecursion(root.right))>1)
358             return false;
359         return isAVLByRecursion(root.left)&&isAVLByRecursion(root.right);
360     }
361 
362     //递归求二叉树的镜像,破坏原有的树
363     public static TreeNode mirrorByRecursion(TreeNode root){
364         if(root==null)
365             return null;
366         TreeNode left=mirrorByRecursion(root.left);
367         TreeNode right=mirrorByRecursion(root.right);
368         root.left=right;
369         root.right=left;
370         return root;
371     }
372     //迭代求二叉树的镜像,破坏原有的树
373     public static void mirrorByLoop(TreeNode root){
374         if(root==null)
375             return;
376         Stack<TreeNode> stack=new Stack<>();
377         stack.push(root);
378 
379         while(!stack.isEmpty()){
380             TreeNode cur=stack.pop();
381             TreeNode tmp=cur.right;
382             cur.right=cur.left;
383             cur.left=tmp;
384 
385             if(cur.left!=null)
386                 stack.push(cur.left);
387             if(cur.right!=null)
388                 stack.push(cur.right);
389         }
390     }
391 
392     //递归求二叉树的镜像,不破坏原有的树
393     public static TreeNode mirrorCopyByRecursion(TreeNode root){
394         if(root==null)
395             return null;
396         TreeNode newNode=new TreeNode(root.val);
397         newNode.left=mirrorCopyByRecursion(root.right);
398         newNode.right=mirrorCopyByRecursion(root.left);
399         return newNode;
400     }
401     //迭代求二叉树的镜像,不破坏原有的树
402     public static TreeNode mirrorCopyByLoop(TreeNode root){
403         if(root==null)
404             return null;
405         Stack<TreeNode> stack=new Stack<>();
406         Stack<TreeNode> newStack=new Stack<>();
407         stack.push(root);
408         TreeNode newRoot=new TreeNode(root.val);
409         newStack.push(newRoot);
410 
411         while(!stack.isEmpty()){
412             TreeNode cur=stack.pop();
413             TreeNode newCur=newStack.pop();
414 
415             if(cur.right!=null){
416                 stack.push(cur.right);
417                 newCur.left=new TreeNode(cur.right.val);
418                 newStack.push(newCur.left);
419             }
420             if(cur.left!=null){
421                 stack.push(cur.left);
422                 newCur.right = new TreeNode(cur.left.val);
423                 newStack.push(newCur.right);
424             }
425         }
426         return newRoot;
427     }
428 
429     //递归判断两棵树是否相互镜像
430     public static boolean isMirrorByRecursion(TreeNode r1,TreeNode r2){
431         if(r1==null&&r2==null)
432             return true;
433         if(r1==null||r2==null)
434             return false;
435         if(r1.val!=r2.val)
436             return false;
437         return isMirrorByRecursion(r1.left,r2.right)&&isMirrorByRecursion(r1.right,r2.left);
438     }
439 
440     //递归求最低公共父节点
441     public static TreeNode getLastCommonParentByRecursion(TreeNode root,TreeNode n1,TreeNode n2){
442         if(root==null||root==n1||root==n2)
443             return root;
444         TreeNode left=getLastCommonParentByRecursion(root.left,n1,n2);
445         TreeNode right=getLastCommonParentByRecursion(root.right,n1,n2);
446         return left==null?right:right==null?left:root;
447     }
448     //迭代求最低公共父节点
449     //todo
450     public static TreeNode getLastCommonParentByLoop(TreeNode root,TreeNode n1,TreeNode n2){
451         Map<TreeNode,TreeNode> parent = new HashMap<>();
452         Deque<TreeNode> stack = new ArrayDeque<>();
453         parent.put(root,null);
454         stack.push(root);
455 
456         while(!parent.containsKey(n1)||!parent.containsKey(n2)){
457             TreeNode node = stack.pop();
458             if(node.left!=null){
459                 parent.put(node.left,node);
460                 stack.push(node.left);
461             }
462             if(node.right!=null){
463                 parent.put(node.right,node);
464                 stack.push(node.right);
465             }
466         }
467         Set<TreeNode> ancestors = new HashSet<>();
468         while(n1!=null){
469             ancestors.add(n1);
470             n1=parent.get(n1);
471         }
472         while(!ancestors.contains(n2))
473             n2=parent.get(n2);
474         return n2;
475     }
476 
477     //递归求二叉树节点最大距离
478     public static int getMaxDistanceByRecursion(TreeNode root){
479         if(root==null)
480             return 0;
481         int k=depth(root.left)+depth(root.right);
482         int left=getMaxDistanceByRecursion(root.left);
483         int right=getMaxDistanceByRecursion(root.right);
484         return Math.max(k,Math.max(left,right));
485     }
486     private static int depth(TreeNode root){
487         if(root==null)
488             return 0;
489         return Math.max(depth(root.left),depth(root.right))+1;
490     }
491 
492     //递归 由前序遍历序列和中序遍历序列重建二叉树
493     //todo
494     public static TreeNode rebuildBinaryTreeByRecursion(int[] preorder,int[] inorder){
495         return buildTree(preorder,0,inorder,inorder.length-1,0);
496     }
497     private static TreeNode buildTree(int[] preorder,int idx,int[] inorder,int end,int start){
498         if(idx>=preorder.length||start>end)
499             return null;
500         TreeNode root = new TreeNode(preorder[idx]);
501         int i;
502         for(i=end;i>=start;i--){
503             if(preorder[idx]==inorder[i])
504                 break;
505         }
506         root.left=buildTree(preorder,idx+1,inorder,i-1,start);
507         root.right=buildTree(preorder,idx+i-start+1,inorder,end,i+1);
508         return root;
509     }
510 
511     //迭代判断二叉树是不是完全二叉树
512     public static boolean isCompleteBinaryTreeByLoop(TreeNode root){
513         if(root==null)
514             return false;
515 
516         Queue<TreeNode> queue=new LinkedList<>();
517         queue.add(root);
518         boolean mustHaveNoChild=false;
519         boolean result=true;
520 
521         while(!queue.isEmpty()){
522             TreeNode cur=queue.remove();
523             if(mustHaveNoChild){
524                 if(cur.left!=null||cur.right!=null){
525                     result=false;
526                     break;
527                 }
528             }else {
529                 if(cur.left!=null&&cur.right!=null){
530                     queue.add(cur.left);
531                     queue.add(cur.right);
532                 }else if(cur.left!=null&&cur.right==null){
533                     mustHaveNoChild=true;
534                     queue.add(cur.left);
535                 }else if(cur.left==null&&cur.right!=null){
536                     result=false;
537                     break;
538                 }else{
539                     mustHaveNoChild=true;
540                 }
541             }
542         }
543         return result;
544     }
545 
546 }

 

全部评论

相关推荐

程序员花海:实习和校招简历正确格式应该是教育背景+实习+项目经历+个人评价 其中项目经历注意要体现业务 实习经历里面的业务更是要自圆其说 简历模板尽可能保持干净整洁 不要太花哨的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务