Java实现栈和队列

栈:LIFO(后进先出)

队列:FIFO(先进先出)

栈的顺序存储结构实现:

* top:栈顶指针,初始化top=-1
* 入栈:data[++top]=e
* 出栈:(E)data[top--]
* 得到栈顶元素:(E)data[top]
* 空:top=-1
 1 package com.myutil.stack;
 2 
 3 /**
 4  * 基于数组实现的顺序栈
 5  * @param <E>
 6  * 
 7  * top:栈顶指针,初始化top=-1
 8  * 入栈:data[++top]=e
 9  * 出栈:(E)data[top--]
10  * 得到栈顶元素:(E)data[top]
11  * 空:top=-1
12  */
13 public class Stack<E> {
14     private Object[] data = null;
15     private int maxSize=0;   //栈容量
16     private int top =-1;  //栈顶指针
17     
18     /**
19      * 构造函数:根据给定的size初始化栈
20      */
21     Stack(){
22         this(10);   //默认栈大小为10
23     }
24     
25     Stack(int initialSize){
26         if(initialSize >=0){
27             this.maxSize = initialSize;
28             data = new Object[initialSize];
29             top = -1;
30         }else{
31             throw new RuntimeException("初始化大小不能小于0:" + initialSize);
32         }
33     }
34     
35     
36     
37     //进栈,第一个元素top=0;
38     public boolean push(E e){
39         if(top == maxSize -1){
40             throw new RuntimeException("栈已满,无法将元素入栈!");
41         }else{
42             data[++top]=e;
43             return true;
44         }    
45     }
46     
47     //查看栈顶元素但不移除
48     public E peek(){
49         if(top == -1){
50             throw new RuntimeException("栈为空!");
51         }else{
52             return (E)data[top];
53         }
54     }
55     
56     //弹出栈顶元素
57     public E pop(){
58         if(top == -1){
59             throw new RuntimeException("栈为空!");
60         }else{
61             return (E)data[top--];
62         }
63     }
64     
65     //判空
66     public boolean empty(){
67         return top==-1 ? true : false;
68     }
69     
70     //返回对象在堆栈中的位置,以 1 为基数
71     public int search(E e){
72         int i=top;
73         while(top != -1){
74             if(peek() != e){
75                 top --;
76             }else{
77                 break;
78             }
79         }
80         int result = top+1;
81         top = i;
82         return result;      
83     }
84     
85     public static void main(String[] args) {
86         Stack<Integer> stack=new Stack<>();
87         for (int i = 0; i < 5; i++) {
88             stack.push(i);
89         }
90         for (int i = 0; i < 5; i++) {
91             System.out.print(stack.pop()+" ");
92         }
93     }
94 }

栈的链式存储结构实现:

 1 package com.myutil.stack;
 2 
 3 public class LinkStack<E> {
 4     //链栈的节点
 5     private class Node<E>{
 6         E e;
 7         Node<E> next;
 8         
 9         public Node(){}
10         public Node(E e, Node next){
11             this.e = e;
12             this.next = next;
13         }
14     }
15     
16     private Node<E> top;   //栈顶元素
17     private int size;  //当前栈大小
18     
19     public LinkStack(){
20         top = null;
21     }
22     
23     
24     
25     //入栈:让top指向新创建的元素,新元素的next引用指向原来的栈顶元素
26     public boolean push(E e){
27         top = new Node(e,top);
28         size ++;
29         return true;
30     }
31     
32     //查看栈顶元素但不删除
33     public Node<E> peek(){
34         if(empty()){
35             throw new RuntimeException("空栈异常!");
36         }else{
37             return top;
38         }
39     }
40     
41     //出栈
42     public Node<E> pop(){
43         if(empty()){
44             throw new RuntimeException("空栈异常!");
45         }else{
46             Node<E> value = top; //得到栈顶元素
47             top = top.next; //让top引用指向原栈顶元素的下一个元素 
48             value.next = null;  //释放原栈顶元素的next引用
49             size --;
50             return value;
51         }
52     }
53     
54   //当前栈大小
55     public int length(){
56         return size;
57     }
58     
59     //判空
60     public boolean empty(){
61         return size==0;
62     }
63     
64     public static void main(String[] args) {
65         LinkStack<Integer> stack=new LinkStack<>();
66         for (int i = 0; i < 5; i++) {
67             stack.push(i);
68         }
69         for (int i = 0; i < 5; i++) {
70             System.out.print(stack.pop().e+" ");
71         }
72     }
73 }

基于LinkedList实现的栈结构:

 * push-----addFirst()
 * pop------removeFirst()
 * peek-----getFirst()
 * empty----isEmpty()
 1 package com.myutil.stack;
 2 
 3 import java.util.LinkedList;
 4 
 5 /**
 6  * 基于LinkedList实现栈
 7  * 在LinkedList实力中只选择部分基于栈实现的接口
 8  * 
 9  * push-----addFirst()
10  * pop------removeFirst()
11  * peek-----getFirst()
12  * empty----isEmpty()
13  */
14 public class StackList<E> {
15     private LinkedList<E> ll = new LinkedList<E>();
16     
17     //入栈
18     public void push(E e){
19         ll.addFirst(e);
20     }
21     
22     //查看栈顶元素但不移除
23     public E peek(){
24         return ll.getFirst();
25     }
26     
27     //出栈
28     public E pop(){
29         return ll.removeFirst();
30     }
31     
32     //判空
33     public boolean empty(){
34         return ll.isEmpty();
35     }
36     
37     //打印栈元素
38     public String toString(){
39         return ll.toString();
40     }
41     
42     public static void main(String[] args) {
43         StackList<Integer> stack=new StackList<>();
44         for (int i = 0; i < 5; i++) {
45             stack.push(i);
46         }
47         System.out.println(stack.toString());
48         for (int i = 0; i < 5; i++) {
49             System.out.print(stack.pop()+" ");
50         }
51     }
52 }

队列的顺序存储结构实现

front=rear=0 
入队:rear=rear+1
出队:front=front+1
取队头:队头指针:front

队满:rear=maxSize-1
对空:rear==front
对长:rear-front

如果实现一个简单的只有入队和出队功能的队列:可以设置front=0,rear=-1
 1 package com.myutil.queue;
 2 
 3 public class Queue<E> {
 4     private Object[] data=null;
 5     private int maxSize; //队列容量
 6     private int front;  //队列头,允许删除
 7     private int rear;   //队列尾,允许插入
 8 
 9     //构造函数
10     public Queue(){
11         this(10);
12     }
13     
14     public Queue(int initialSize){
15         if(initialSize >=0){
16             this.maxSize = initialSize;
17             data = new Object[initialSize];
18             front = rear =0;
19         }else{
20             throw new RuntimeException("初始化大小不能小于0:" + initialSize);
21         }
22     }
23     
24     //判空
25     public boolean empty(){
26         return rear==front?true:false;
27     }
28     
29     //插入
30     public boolean add(E e){
31         if(rear== maxSize-1){
32             throw new RuntimeException("队列已满,无法插入新的元素!");
33         }else{
34             data[rear++]=e;
35             return true;
36         }
37     }
38     
39     //返回队首元素,但不删除
40     public E peek(){
41         if(empty()){
42             throw new RuntimeException("空队列异常!");
43         }else{
44             return (E) data[front];
45         }    
46     }
47     
48     //出队
49     public E poll(){
50         if(empty()){
51             throw new RuntimeException("空队列异常!");
52         }else{
53             E value = (E) data[front];  //保留队列的front端的元素的值
54             data[front++] = null;     //释放队列的front端的元素                
55             return value;
56         }            
57     }
58     
59     //队列长度
60     public int length(){
61         return rear-front;
62     }
63     
64     public static void main(String[] args) {
65         Queue<Integer> queue=new Queue<>();
66         for (int i = 0; i < 5; i++) {
67             queue.add(i);
68         }
69         for (int i = 0; i < queue.length(); i++) {
70             System.out.print(queue.peek()+" ");
71         }
72         System.out.println();
73         int size=queue.length();
74         for (int i = 0; i < size; i++) {
75             System.out.print(queue.poll()+" ");
76         }
77     }
78 }

循环队列的顺序存储结构实现

front=rear=0

入队:rear=(rear+1)/maxSize
出队:front=(front+1)/maxSize

取队头:队头指针:front
队满:(rear+1)/maxSize=front(如果不设置变量size来判断队满)

队空:rear=front
对长:rear-front
  1 package com.myutil.queue;
  2 
  3 /*
  4  * 入队:rear=(rear+1)%maxSize,data[rear]=e
  5  * 出队:front = (front+1)%maxSize; E value =(E)data[front]; data[front] = null; 
  6  * 得到对首元素:(E)data[front+1];
  7  * 判断对空:rear==front
  8  * 对长:rear-front
  9  */
 10 import java.util.Arrays;
 11 
 12 import java.util.Arrays;
 13 
 14 public class LoopQueue<E> {
 15     public Object[] data = null;
 16     private int maxSize; // 队列容量
 17     private int rear;// 队列尾,允许插入
 18     private int front;// 队列头,允许删除
 19     private int size=0; //队列当前长度
 20 
 21     public LoopQueue() {
 22         this(10);
 23     }
 24 
 25     public LoopQueue(int initialSize) {
 26         if (initialSize >= 0) {
 27             this.maxSize = initialSize;
 28             data = new Object[initialSize];
 29             front = rear = 0;
 30         } else {
 31             throw new RuntimeException("初始化大小不能小于0:" + initialSize);
 32         }
 33     }
 34 
 35     // 判空
 36     public boolean empty() {
 37         return size == 0;
 38     }
 39 
 40     // 插入
 41     public boolean add(E e) {
 42         if (size == maxSize) {
 43             throw new RuntimeException("队列已满,无法插入新的元素!");
 44         } else {
 45             data[rear] = e;
 46             rear = (rear + 1)%maxSize;
 47             size ++;
 48             return true;
 49         }
 50     }
 51 
 52     // 返回队首元素,但不删除
 53     public E peek() {
 54         if (empty()) {
 55             throw new RuntimeException("空队列异常!");
 56         } else {
 57             return (E) data[front];
 58         }
 59     }
 60 
 61     // 出队
 62     public E poll() {
 63         if (empty()) {
 64             throw new RuntimeException("空队列异常!");
 65         } else {
 66             E value = (E) data[front]; // 保留队列的front端的元素的值
 67             data[front] = null; // 释放队列的front端的元素
 68             front = (front+1)%maxSize;  //队首指针加1
 69             size--;
 70             return value;
 71         }
 72     }
 73 
 74     // 队列长度
 75     public int length() {
 76         return size;
 77     }
 78 
 79     //清空循环队列
 80     public void clear(){
 81         Arrays.fill(data, null);
 82         size = 0;
 83         front = 0;
 84         rear = 0;
 85     }
 86     
 87     public static void main(String[] args) {
 88         LoopQueue<Integer> queue=new LoopQueue<>();
 89         for (int i = 0; i < 5; i++) {
 90             queue.add(i);
 91         }
 92         for (int i = 0; i < queue.length(); i++) {
 93             System.out.print(queue.peek()+" ");
 94         }
 95         System.out.println();
 96         int size=queue.length();
 97         for (int i = 0; i < size; i++) {
 98             System.out.print(queue.poll()+" ");
 99         }
100     }
101 }

队列的链式存储结构实现

 1 package com.myutil.queue;
 2 
 3 public class LinkQueue<E> {
 4     // 链栈的节点
 5     private class Node<E> {
 6         E e;
 7         Node<E> next;
 8 
 9         public Node() {
10         }
11 
12         public Node(E e, Node next) {
13             this.e = e;
14             this.next = next;
15         }
16         
17     }
18     
19     private Node front;// 队列头,允许删除  
20     private Node rear;// 队列尾,允许插入  
21     private int size; //队列当前长度 
22     
23     public LinkQueue() {
24         front = null;
25         rear = null;
26     }
27     
28     //判空
29       public boolean empty(){
30           return size==0;
31       }
32       
33       //插入
34       public boolean add(E e){
35           if(empty()){    //如果队列为空
36               front = new Node(e,null);//只有一个节点,front、rear都指向该节点
37               rear = front;
38           }else{
39               Node<E> newNode = new Node<E>(e, null);
40               rear.next = newNode; //让尾节点的next指向新增的节点
41               rear = newNode; //以新节点作为新的尾节点
42           }
43           size ++;
44           return true;
45       }
46       
47       //返回队首元素,但不删除
48       public Node<E> peek(){
49           if(empty()){
50               throw new RuntimeException("空队列异常!");
51           }else{
52               return front;
53           }
54       }
55       
56       //出队
57       public Node<E> poll(){
58           if(empty()){
59               throw new RuntimeException("空队列异常!");
60           }else{
61               Node<E> value = front; //得到队列头元素
62               front = front.next;//让front引用指向原队列头元素的下一个元素
63               value.next = null; //释放原队列头元素的next引用
64               size --;
65               return value;
66           }        
67       }
68       
69       //队列长度
70       public int length(){
71           return size;
72       }
73       
74       public static void main(String[] args) {
75           LinkQueue<Integer> queue=new LinkQueue<>();
76           for (int i = 0; i < 5; i++) {
77               queue.add(i);
78           }
79           for (int i = 0; i < queue.length(); i++) {
80               System.out.print(queue.peek().e+" ");
81           }
82           System.out.println();
83           int size=queue.length();
84           for (int i = 0; i < size; i++) {
85               System.out.print(queue.poll().e+" ");
86           }
87       }
88 }

基于LinkedList实现队列结构

 * 使用java.util.Queue接口,其底层关联到一个LinkedList(双端队列)实例.
 * 
 * add----add()            会抛出异常
 * offer-----offer()
 * 
 * element-----element() 对为空,返回异常
 * peek------peek()
 * 
 * remove----remove() 对为空,返回异常
 * poll------poll()
 * 
 * empty-----isEmpty()
 1 package com.myutil.queue;
 2 
 3 /**
 4  * 使用java.util.Queue接口,其底层关联到一个LinkedList(双端队列)实例.
 5  * 
 6  * add----add()            会抛出异常
 7  * offer-----offer()
 8  * 
 9  * element-----element() 对为空,返回异常
10  * peek------peek()
11  * 
12  * remove----remove() 对为空,返回异常
13  * poll------poll()
14  * 
15  * empty-----isEmpty()
16  */
17 import java.util.LinkedList;
18 import java.util.Queue;
19 
20 public class QueueList<E> {
21     private Queue<E> queue = new LinkedList<E>();
22     
23     // 将指定的元素插入此队列(如果立即可行且不会违反容量限制),在成功时返回 true,
24     //如果当前没有可用的空间,则抛出 IllegalStateException。
25     public boolean add(E e){
26         return queue.add(e);
27     }
28     
29     //获取,但是不移除此队列的头。
30     public E element(){
31         return queue.element();
32     }
33     
34     //将指定的元素插入此队列(如果立即可行且不会违反容量限制),当使用有容量限制的队列时,
35     //此方法通常要优于 add(E),后者可能无法插入元素,而只是抛出一个异常。
36     public boolean offer(E e){
37         return queue.offer(e);
38     }
39     
40     //获取但不移除此队列的头;如果此队列为空,则返回 null
41     public E peek(){
42         return queue.peek();
43     }
44     
45     //获取并移除此队列的头,如果此队列为空,则返回 null
46     public E poll(){
47         return queue.poll();
48     }
49     
50     //获取并移除此队列的头
51     public E remove(){
52         return queue.remove();
53     }
54     
55     //判空
56     public boolean empty() {
57         return queue.isEmpty();
58     }
59     public static void main(String[] args) {
60           QueueList<Integer> queueList=new QueueList<>();
61           for (int i = 0; i < 5; i++) {
62               queueList.add(i);
63           }
64           /*while (!queueList.empty()) {
65             System.out.println(queueList.peek());
66         }
67           System.out.println();
68           */
69           while (!queueList.empty()) {
70             System.out.print(queueList.poll()+" ");
71         }
72       }
73 }

本文参考地址:http://www.cnblogs.com/CherishFX/p/4608880.html 并在此博客的基础上进行了一些修改

原文地址:https://www.cnblogs.com/midiyu/p/8168618.html