数据结构

Posted sakura1027

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构相关的知识,希望对你有一定的参考价值。

栈和队列

1. 栈的实现

 1 //基于数组实现的栈
 2 public class ArrayStack {
 3     private int[] arr;
 4     private int top;
 5 
 6     ArrayStack(int initialSize){
 7         if(initialSize<=0)
 8             throw new RuntimeException("栈初始化容量参数错误:"+initialSize);
 9         top=-1;
10         arr=new int[initialSize];
11     }
12 
13     public int push(int x){
14         if(top==arr.length-1)
15             throw new RuntimeException("栈已满,无法入栈!");
16         arr[++top]=x;
17         return x;
18     }
19 
20     public int pop(){
21         if(top<0)
22             throw new RuntimeException("栈为空!");
23         return arr[top--];
24     }
25 
26     public int peek(){
27         if(top<0)
28             throw new RuntimeException("栈为空!");
29         return arr[top];
30     }
31 
32     public boolean isEmpty(){
33         return top==-1;
34     }
35 
36     public static void main(String[] args) {
37         ArrayStack ms=new ArrayStack(10);
38         for(int i=0;i<5;i++)
39             System.out.println("添加了"+ms.push(i));
40         System.out.println("栈是否为空:"+ms.isEmpty());
41         System.out.println(ms.peek());
42         for(int i=0;i<5;i++)
43             System.out.println("删除了"+ms.pop());
44         System.out.println(ms.isEmpty());
45         ms.peek();
46     }
47 }
48 /*
49 Exception in thread "main" java.lang.RuntimeException: 栈为空!
50 添加了0
51 添加了1
52     at com.sakura.alg.ArrayStack.peek(ArrayStack.java:31)
53 添加了2
54     at com.sakura.alg.ArrayStack.main(ArrayStack.java:48)
55 添加了3
56 添加了4
57 栈是否为空:false
58 4
59 删除了4
60 删除了3
61 删除了2
62 删除了1
63 删除了0
64 true
65  */
 1 import java.util.EmptyStackException;
 2 import java.util.LinkedList;
 3 
 4 //基于链表实现的栈
 5 public class ListStack {
 6     private LinkedList<Integer> l=new LinkedList<>();
 7 
 8     public int push(int x){
 9         l.addLast(x);
10         return x;
11     }
12 
13     public int pop(){
14         if(l.size()<=0)
15             throw new EmptyStackException();
16         return l.removeLast();
17     }
18 
19     public int peek(){
20         if(l.size()<=0)
21             throw new EmptyStackException();
22         return l.getLast();
23     }
24 
25     public boolean isEmpty(){
26         return l.size()==0;
27     }
28 
29     public static void main(String[] args) {
30         ListStack ms=new ListStack();
31         for(int i=0;i<5;i++)
32             System.out.println("添加了"+ms.push(i));
33         System.out.println("栈是否为空:"+ms.isEmpty());
34         System.out.println(ms.peek());
35         for(int i=0;i<5;i++)
36             System.out.println("删除了"+ms.pop());
37         System.out.println(ms.isEmpty());
38         ms.peek();
39     }
40 }
41 /*
42 Exception in thread "main" java.util.EmptyStackException
43 添加了0
44     at com.sakura.alg.ListStack.peek(ListStack.java:23)
45 添加了1
46     at com.sakura.alg.ListStack.main(ListStack.java:40)
47 添加了2
48 添加了3
49 添加了4
50 栈是否为空:false
51 4
52 删除了4
53 删除了3
54 删除了2
55 删除了1
56 删除了0
57 true
58  */

2. 队列实现

 1 public class ArrayQueue {
 2     private int[] arr;
 3     private int head;
 4     private int tail;
 5 
 6     ArrayQueue(int initialSize){
 7         if(initialSize<=0)
 8             throw new RuntimeException("队列初始化容量参数错误:"+initialSize);
 9         arr=new int[initialSize];
10         head=tail=0;
11     }
12 
13     public boolean isEmpty(){
14         return tail<=0||head>=tail;
15     }
16 
17     public int add(int x){
18         if(tail==arr.length)
19             throw new RuntimeException("队列已满,无法入队!");
20         arr[tail++]=x;
21         return x;
22     }
23 
24     public int peek(){
25         if(tail<=0||head>=tail)
26             throw new RuntimeException("队列为空!");
27         return arr[head];
28     }
29 
30     public int poll(){
31         if(tail<=0||head>=tail)
32             throw new RuntimeException("队列为空!");
33         return arr[head++];
34     }
35 
36     public static void main(String[] args) {
37         ArrayQueue mq=new ArrayQueue(10);
38         for(int i=0;i<5;i++)
39             System.out.println("添加了"+mq.add(i));
40         System.out.println("队列是否为空:"+mq.isEmpty());
41         System.out.println(mq.peek());
42         for(int i=0;i<5;i++)
43             System.out.println("删除了"+mq.poll());
44         System.out.println(mq.isEmpty());
45         mq.peek();
46     }
47 
48 }
49 /*
50 Exception in thread "main" java.lang.RuntimeException: 队列为空!
51 添加了0
52 添加了1
53 添加了2
54 添加了3
55 添加了4
56 队列是否为空:false
57 0
58     at com.sakura.alg.ArrayQueue.peek(ArrayQueue.java:28)
59 删除了0
60     at com.sakura.alg.ArrayQueue.main(ArrayQueue.java:47)
61 删除了1
62 删除了2
63 删除了3
64 删除了4
65 true
66  */
 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     public static void main(String[] args) {
24         ListQueue mq=new ListQueue();
25         for(int i=0;i<5;i++)
26             mq.offer(i);
27         System.out.println("队列是否为空:"+mq.isEmpty());
28         System.out.println(mq.peek());
29         for(int i=0;i<5;i++)
30             System.out.println("删除了"+mq.poll());
31         System.out.println(mq.isEmpty());
32         mq.peek();
33     }
34 
35 }
36 /*
37 队列是否为空:false
38 Exception in thread "main" java.lang.NullPointerException
39     at com.sakura.alg.ListQueue.peek(ListQueue.java:10)
40 0
41     at com.sakura.alg.ListQueue.main(ListQueue.java:34)
42 删除了0
43 删除了1
44 删除了2
45 删除了3
46 删除了4
47 true
48  */

3. 两个栈实现一个队列

 1 import java.util.Stack;
 2 
 3 public class MyQueue {
 4     private Stack<Integer> stack=new Stack<>();
 5     private Stack<Integer> stack2=new Stack<>();
 6 
 7     public int offer(int x){
 8         stack.push(x);
 9         return x;
10     }
11 
12     public int poll(){
13         if(stack2.isEmpty())
14             while(!stack.isEmpty())
15                 stack2.push(stack.pop());
16 
17         if(stack2.isEmpty())
18             throw new RuntimeException("队列为空!");
19         return stack2.pop();
20     }
21 
22     public static void main(String[] args) {
23         MyQueue mq=new MyQueue();
24         for(int i=0;i<5;i++)
25             mq.offer(i);
26         mq.poll();
27         System.out.println(mq.poll());//1
28     }
29     
30 }

4. 两个队列实现一个栈

 1 import java.util.LinkedList;
 2 import java.util.Queue;
 3 
 4 public class MyStack {
 5     private Queue<Integer> queue1=new LinkedList<>();
 6     private Queue<Integer> queue2=new LinkedList<>();
 7 
 8     public int push(int x){
 9         if(!queue1.isEmpty())
10             queue1.offer(x);
11         else
12             queue2.offer(x);
13         return x;
14     }
15 
16     public int pop(){
17         if(queue1.isEmpty()&&queue2.isEmpty())
18             throw new RuntimeException("栈为空!");
19         if(queue1.isEmpty()){
20             while(queue2.size()>1)
21                 queue1.offer(queue2.poll());
22             return queue2.poll();
23         }else{
24             while(queue1.size()>1)
25                 queue2.offer(queue1.poll());
26             return queue1.poll();
27         }
28     }
29 
30     public static void main(String[] args) {
31         MyStack ms=new MyStack();
32         for(int i=0;i<5;i++)
33             System.out.println("添加了"+ms.push(i));
34         System.out.println(ms.pop());
35 
36         System.out.println("添加了"+ms.push(5));
37         for(int i=0;i<5;i++)
38             System.out.println(ms.pop());
39     }
40 
41 }
42 /*
43 添加了0
44 添加了1
45 添加了2
46 添加了3
47 添加了4
48 4
49 添加了5
50 5
51 3
52 2
53 1
54 0
55  */

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 SeqStack {
 4     public static boolean IsPopOrder(int [] pushA,int [] popA) {
 5         Stack<Integer> s = new Stack<>();
 6         int popIndex = 0;
 7         for(int i = 0; i< pushA.length;i++){
 8             s.push(pushA[i]);
 9             while(!s.empty() &&s.peek() == popA[popIndex]){
10                 s.pop();
11                 popIndex++;
12             }
13         }
14         return s.empty();
15     }
16 
17     public static void main(String[] args) {
18         int[] arr={1,2,3,4,5};
19         int[] brr={5,4,3,2,1};
20         System.out.println(IsPopOrder(arr,brr));
21     }
22 }

链表

  1 import java.util.Stack;
  2 
  3 public class LinkList {
  4     static class Node {
  5         int data;
  6         Node next;
  7 
  8         public Node(int data) {
  9             this.data = data;
 10         }
 11     }
 12 
 13     public Node head;
 14     public Node current;
 15 
 16     //创建链表
 17     public void add(int data) {
 18         if (head == null) {
 19             head = new Node(data);
 20             current = head;
 21         } else {
 22             current.next = new Node(data);
 23             current = current.next;
 24         }
 25     }
 26 
 27     public void add(Node node) {
 28         if (node == null)
 29             return;
 30         if (head == null) {
 31             head = node;
 32             current = head;
 33         } else {
 34             current.next = node;
 35             current = current.next;
 36         }
 37     }
 38 
 39     //遍历输出链表
 40     public static void print(Node node) {
 41         if (node == null)
 42             return;
 43         Node current = node;
 44         while (current.next != null) {
 45             System.out.print(current.data+"->");
 46             current = current.next;
 47         }
 48         System.out.println(current.data);
 49     }
 50 
 51     //获得链表节点个数
 52     public static int getLength(Node head){
 53         if(head==null)
 54             return 0;
 55         int count=0;
 56         Node current=head;
 57         while(current!=null){
 58             count++;
 59             current=current.next;
 60         }
 61         return count;
 62     }
 63 
 64     //查找倒数第k个节点
 65     public static int findLastNode(Node head,int k){
 66         if(k==0||head==null)
 67             return -1;
 68         int size=getLength(head);
 69         if(k>size)
 70             return -1;
 71         Node cur=head;
 72         for(int i=0;i<size-k;i++){
 73             cur=cur.next;
 74         }
 75         return cur.data;
 76     }
 77 
 78     //在不允许遍历链表长度的情况下查找倒数第k个节点
 79     public static int findLastNode2(Node head,int k){
 80         if(k==0||head==null)
 81             return -1;
 82         Node first=head,second=head;
 83         for(int i=0;i<k-1;i++){
 84             second=second.next;
 85             if(second==null)
 86                 return -1;
 87         }
 88 
 89         while(second.next!=null){
 90             first=first.next;
 91             second=second.next;
 92         }
 93         return first.data;
 94     }
 95 
 96     //查找中间节点
 97     public static int findMidNode(Node head){
 98         if(head==null)
 99             return -1;
100         Node first=head,second=head;
101         while(second!=null&&second.next!=null){
102             first=first.next;
103             second=second.next.next;
104         }
105         return first.data;
106     }
107 
108     //合并两个有序链表
109     public static Node mergeTwoLists(Node l1, Node l2) {
110         if(l1==null)
111             return l2;
112         if(l2==null)
113             return l1;
114         if(l1.data < l2.data){
115             l1.next = mergeTwoLists(l1.next, l2);
116             return l1;
117         } else{
118             l2.next = mergeTwoLists(l1, l2.next);
119             return l2;
120         }
121     }
122 
123     //循环翻转
124     public static Node ReverseListByLoop(Node head) {
125         Node pre = null;
126         Node next = null;
127         while(head!=null){
128             next = head.next;
129             head.next = pre;
130             pre = head;
131             head = next;
132         }
133         return pre;
134     }
135 
136     //递归翻转
137     public static Node ReverseListByRecursion(Node head){
138         if(head==null||head.next ==null)
139             return head;
140         Node prev = ReverseListByRecursion(head.next);
141         head.next.next = head;
142         head.next = null;
143         return prev;
144     }
145 
146     //从尾到头打印链表
147     public static void reversePrint(Node head){
148         if(head==null)
149             return;
150         Stack<Node> stack=new Stack<>();
151         Node current=head;
152         while(current!=null){
153             stack.push(current);
154             current=current.next;
155         }
156         while(!stack.isEmpty()){
157             System.out.print(stack.pop().data+" ");
158         }
159         System.out.println();
160     }
161 
162     //判断单链表是否有环
163     public static Node hasCycle(Node head) {
164         if(head==null)
165             return null;
166         Node first = head,second=head;
167 
168         while (second != null&&second.next!=null) {
169             first = first.next;
170             second = second.next.next;
171             if (first == second)
172                 return first;
173         }
174         return null;
175     }
176 
177     //获取有环链表的环的长度
178     public static int getCycleLength(Node node) {
179         Node current = node;
180         int length = 0;
181         while (current != null) {
182             current = current.next;
183             length++;
184             if (current == node)
185                 return length;
186         }
187         return length;
188     }
189 
190     //取出环的起点
191     public static Node getCycleStart(Node head) {
192         if(head==null)
193             return null;
194         Node first = head,second=head;
195 
196         while (second != null&&second.next!=null) {
197             first = first.next;
198             second = second.next.next;
199             if (first == second){
200                 second=head;
201                 /*
202                 假设链表起点到环的起点为x
203                 链表起点到快慢指针相遇节点为x+z
204                 环的长度为y
205                 那么有2(x+z)-(x+z)=k*y
206                 即x=k*y-z=y-z+(k-1)*y
207                  */
208                 while(first!=second){
209                     first=first.next;
210                     second=second.next;
211                 }
212                 return first;
213             }
214 
215         }
216         return null;
217     }
218 
219     /*
220     判断两个单链表相交的第一个节点
221     1.压入栈中,依次比较找出最后一个相同的节点,时间空间复杂度均为O(len1+len2)
222     2.快慢指针
223      */
224     public static Node getFirstCommonNode(Node head1, Node head2) {
225         if (head1 == null || head2 == null)
226             return null;
227         int length1 = getLength(head1);
228         int length2 = getLength(head2);
229         int lengthDif=Math.abs(length1-length2);
230         Node longHead=length1>length2?head1:head2,
231         shortHead=length1>length2?head2:head1;
232 
233         for (int i = 0; i < lengthDif; i++)
234             longHead = longHead.next;
235 
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     public static void main(String[] args) {
246         LinkList list = new LinkList();
247         for (int i = 0; i < 10; i++) {
248             list.add(i);
249         }
250         print(list.head);
251         System.out.println(getLength(list.head));
252         System.out.println(findLastNode(list.head,4));
253         System.out.println(findLastNode2(list.head,10));
254         System.out.println(findMidNode(list.head));
255 
256         LinkList list2=new LinkList();
257         for(int i=0;i<10;i+=2){
258             list2.add(i);
259         }
260         print(list2.head);
261         LinkList list3=new LinkList();
262         for(int i=1;i<10;i+=2){
263             list3.add(i);
264         }
265         print(list3.head);
266         print(mergeTwoLists(list2.head,list3.head));
267 
268         Node head=ReverseListByLoop(list.head);
269         print(head);
270         print(ReverseListByRecursion(head));
271 
272         reversePrint(list.head);
273 
274         System.out.println(hasCycle(list.head));
275 
276         LinkList list4=new LinkList();
277         for(int i=0;i<10;i++){
278             list4.add(i);
279         }
280         list4.add(list4.head.next);
281 
282         System.out.println(getCycleLength(hasCycle(list4.head)));
283         System.out.println(getCycleStart(list4.head).data);
284 
285         Node n1=new Node(1);
286         Node n2=new Node(2);
287         Node n3=new Node(3);
288         Node n4=new Node(4);
289         Node n5=new Node(5);
290 
291         LinkList list5=new LinkList();
292         list5.add(n1);
293         list5.add(n2);
294         list5.add(n3);
295         list5.add(n4);
296         list5.add(n5);
297         LinkList list6=new LinkList();
298         list6.add(n2);
299         list6.add(n3);
300         list6.add(n4);
301         list6.add(n5);
302         System.out.println(getFirstCommonNode(list5.head,list6.head).data);
303     }
304 
305 }

 

以上是关于数据结构的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段5——HTML元素结构

超级有用的9个PHP代码片段

python 用于数据探索的Python代码片段(例如,在数据科学项目中)

将代码片段插入数据库并在 textarea 中以相同方式显示

分享几个实用的代码片段(第二弹)

分享几个实用的代码片段(第二弹)