🎈栈和队列是两种特有的存储数据的结构,栈是后进先出的一种结构,队列是先进先出的一种结构。
🎈由于这种特有的结构,在选择底层存储方式也有差异。由于栈是后进先出的结构,其实就是尾删,尾增操作,如果用顺序表来存储,尾删、尾增时间复杂度则是O(1)。链表则需考虑链表的结构,如果是单链表,找尾的时间复杂度就是O(n)。如果是记录尾的双向链表,时间复杂度是O(1)。Java中也封装了这样的集合结构(Stack),用的就是顺序表。由于队列是先进先出的结构,其实就是头删,尾增操作。如果用顺序表存储,头删时间复杂度是O(n),需要挪动数据。如果用链表存储,不论是单链表还是双向链表(记录尾),头删、尾增操作时间复杂度都是O(1)。Java中也封装了这样的结构(Queue),是LinkedList实现的接口,用的是双向链表。这里用的是记录尾的单链表实现。
🎈两种不同的结构的存在,为我们实际处理一些数据提供了便利。
- import java.util.Arrays;
-
- public class Mystack {
-
- private static final int DEFAULT_SIZE = 10;
- private int[] elem;
- private int top;
- public Mystack() {
- elem = new int[DEFAULT_SIZE];
- }
- //压栈
- public int push(int val) {
- if(size() == elem.length) {
- this.elem = Arrays.copyOf(elem, elem.length * 2);
- }
- this.elem[top] = val;
- this.top++;
- return val;
- }
- public int pop() {
- if(empty()) {
- throw new NullStackExpection("栈为空");
- }
- return this.elem[--top];
- }
- public int peek() {
- if(empty()) {
- throw new NullStackExpection("栈为空");
- }
- return this.elem[top - 1];
- }
- public int size() {
- return this.top;
- }
- public boolean empty() {
- return size() == 0;
- }
- }
- public class MyQueue {
- static class ListNode {
- private int val;
- private ListNode next;
- public ListNode(int val) {
- this.val = val;
- }
- }
- private int usedSize;
- private ListNode head;
- private ListNode tail;
- public void offer(int date) {
- ListNode newNode = new ListNode(date);
- if(head == null) {
- head = newNode;
- tail = newNode;
- this.usedSize++;
- return;
- }
- tail.next = newNode;
- tail = tail.next;
- this.usedSize++;
-
- }
- public int poll() {
- if(empty()) {
- throw new NullQueueExpection("空队列");
- }
- //只有一个节点特殊处理
- if(head.next == null) {
- int tmp = head.val;
- head = null;
- tail = null;
- this.usedSize--;
- return tmp;
- }
- int tmp = head.val;
- head = head.next;
- this.usedSize--;
- return tmp;
- }
- public int peek() {
- if(empty()) {
- throw new NullQueueExpection("空队列");
- }
- return this.head.val;
- }
-
- public int size() {
- return this.usedSize;
- }
- public boolean empty() {
- return this.usedSize == 0;
- }
- }
🐵我们需熟悉这样的数据结构,理解底层存储原理,在实际对数据操作中才能得心应手。