• 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 并在此博客的基础上进行了一些修改

  • 相关阅读:
    PHP的常用框架有哪些?
    Django中反向生成models
    Django中使用django_debug_toolbar
    Django日志系统
    RESTful接口规范
    Django restframework
    Mysql数据备份与还原
    CORS解决跨域问题
    Linux下Python2升级Python3
    Django+Uwsgi+Nginx部署
  • 原文地址:https://www.cnblogs.com/midiyu/p/8168618.html
Copyright © 2020-2023  润新知