zoukankan      html  css  js  c++  java
  • 数据结构之队列、栈

    背包、队列和栈

    前言: 我们为包,队列和堆栈定义API。除了基础知识,这些API反映了两个Java特性:泛型和可迭代集合。

    背包:

        一种不支持删除操作的数据结构,目的是为了帮助用例搜集元素并迭代遍历所有元素。比如一个人喜欢搜集各种石头,他将搜集到的石头都放到一个包里,一次一个,这些搜集到的石头他都很喜欢,不会扔掉,并且有时还会从背包里找出具有某些特征的石头。在这种数据结构中,顺序显得一点也不重要。

    队列:

      一种基于先进先出策略的集合类型,按照他们到达的顺序执行任务的政策是我们在日常生活中经常遇到的任务:从在剧院排队等候的人,到在收费站排队等候的车,到等待应用程序提供服务的任务。

    栈:

     一种基于先进后出策略的集合类型,例如:单击超链接时,浏览器将显示新页面(并将其推送到堆栈)。您可以继续单击超链接以访问新页面,但您可以通过单击后退按钮(从堆栈中弹出)来重新访问上一页

    实现:

      定容栈:

       我们用一个数组来存储压入栈中的元素。

     1 public class FixedCapacityStack<T> {
     2     private T[] ary;
     3     private int N;
     4     public FixedCapacityStack(int cap)
     5     {
     6         ary=(T[])new Object[cap];
     7         N=0;
     8         
     9     }
    10     public boolean isEmpty()
    11     {
    12         return N==0;
    13     }
    14     
    15     public int size()
    16     {
    17         return N;
    18     }
    19     
    20     public void push(T t)
    21     {
    22         
    23         ary[N++]=t;
    24     }
    25     public T pop()
    26     {
    27         return ary[--N];
    28     }
    29 
    30 }
    View Code

    调整数组大小:

     1 public class ResizingArrayStack<T> implements Iterable<T> {
     2     private T[] a;         // array of Ts
     3     private int n;            // number of elements on stack
     4 
     5 
     6     public ResizingArrayStack() {
     7         a = (T[]) new Object[2];
     8         n = 0;
     9     }
    10 
    11    
    12     public boolean isEmpty() {
    13         return n == 0;
    14     }
    15 
    16    
    17     public int size() {
    18         return n;
    19     }
    20 
    21 
    22    
    23     private void resize(int capacity) {
    24         assert capacity >= n;
    25 
    26       
    27         T[] temp = (T[]) new Object[capacity];
    28         for (int i = 0; i < n; i++) {
    29             temp[i] = a[i];
    30         }
    31         a = temp;
    32 
    33     }
    34 
    35 
    36 
    37     
    38     public void push(T T) {
    39         if (n == a.length) resize(2*a.length);   
    40         a[n++] = T;                           
    41     }
    42 
    43    
    44     public T pop() {
    45         if (isEmpty()) throw new NoSuchElementException("Stack underflow");
    46         T T = a[n-1];
    47         a[n-1] = null;                            
    48         n--;
    49        
    50         if (n > 0 && n == a.length/4) resize(a.length/2);
    51         return T;
    52     }
    53 
    54 
    55    
    56     public T peek() {
    57         if (isEmpty()) throw new NoSuchElementException("Stack underflow");
    58         return a[n-1];
    59     }
    60 
    61     public Iterator<T> iterator() {
    62         return new ReverseArrayIterator();
    63     }
    64 
    65    
    66     private class ReverseArrayIterator implements Iterator<T> {
    67         private int i;
    68 
    69         public ReverseArrayIterator() {
    70             i = n-1;
    71         }
    72 
    73         public boolean hasNext() {
    74             return i >= 0;
    75         }
    76 
    77         public void remove() {
    78             throw new UnsupportedOperationException();
    79         }
    80 
    81         public T next() {
    82             if (!hasNext()) throw new NoSuchElementException();
    83             return a[i--];
    84         }
    85     }
    86 }
    View Code

    ResizingArrayStack的缺点在于进行某些pop和push操作时会调整数组大小,耗时和数组大小成正比。

    队列实现:

     1 public class ResizingArrayQueue<T> implements Iterable<T> {
     2     private T[] q;         
     3     private int n; 
     4     private int first;
     5     private int last;
     6 
     7 
     8   
     9     public ResizingArrayQueue() {
    10         q = (T[]) new Object[2];
    11         n = 0;
    12         first=0;
    13         last=0;
    14         
    15     }
    16 
    17   
    18     public boolean isEmpty() {
    19         return n == 0;
    20     }
    21 
    22    
    23     public int size() {
    24         return n;
    25     }
    26 
    27 
    28    
    29     private void resize(int capacity) {
    30         assert capacity >= n;
    31 
    32     
    33         T[] temp = (T[]) new Object[capacity];
    34         for (int i = 0; i < n; i++) {
    35             temp[i] = q[(i+first)%q.length];
    36         }
    37        q=temp;
    38        first=0;
    39        last=n;
    40 
    41     }
    42 
    43 
    44 
    45     public void enqueue(T t) {
    46         if (n == q.length) resize(2*q.length);    
    47         q[last++]=t;
    48         if(last==q.length) last=0;
    49         n++;
    50                       
    51     }
    52 
    53    
    54     public T dequeue() {
    55         if (isEmpty()) throw new NoSuchElementException("Queue underflow");
    56         T t = q[first];
    57         q[first] = null;                             
    58         first++;
    59         if(first==q.length) 
    60             first=0;
    61         
    62        
    63         if (n > 0 && n == q.length/4) resize(q.length/2);
    64         return t;
    65     }
    66 
    67 
    68    
    69     public T peek() {
    70         if (isEmpty()) throw new NoSuchElementException("Stack underflow");
    71         return q[n-1];
    72     }
    73 
    74    
    75     public Iterator<T> iterator() {
    76         return new ReverseArrayIterator();
    77     }
    78 
    79   
    80     private class ReverseArrayIterator implements Iterator<T> {
    81         private int i=0;
    82 
    83 
    84         public boolean hasNext() {
    85             return i<n;
    86         }
    87 
    88         public void remove() {
    89             throw new UnsupportedOperationException();
    90         }
    91 
    92         public T next() {
    93             if (!hasNext()) throw new NoSuchElementException();
    94             T t=q[(i+first)%q.length];
    95             i++;
    96             return t;
    97         }
    98     }
    99 }
    View Code

    下面我们使用链表来表示:

    链表:

       链表是一个递归的数据结构,它或者为空、或者指向一个节点的引用,该节点含有一个泛型元素和一个指向另一条链表的引用。

    例如:  private class node

    {  T t;

               Node next;

             }

     构造链表:

         Node first=new Node();

         Node  second=new Node();

         Node third=new Node();

     现在为t赋值,假定t为String类型。

         first.t=”to”;

         second=”be”;

              third=”or”;

          设置next域来连接节点。

             first.next=second;

             second.next=third;

      如图:

       

     在表头插入和删除元素:

     对一个节点操作,要注意先取值保存再赋值。

     插入:

      

     删除:

       

    Java中的垃圾回收会确保老的first节点被回收。

    在表尾插入节点:

       要在链表的末尾插入节点,我们会保留指向列表中最后一个节点的链接:

     

    如果想在任意位置插入删除,需要用到双向链表(Java就是这么做的),在阅读源码系列里再讨论。

    遍历:

       for(Node x=first;x!=null;x=x.next)

      {

          x.t;

      }

    具体实现:

    栈的链表实现:

     1 public class Stack<T> implements Iterable<T> {
     2     private Node<T> first;
     3     private int n;
     4     
     5     public Stack()
     6     {
     7         first=null;
     8         n=0;
     9     }
    10     public boolean isEmpty()
    11     {
    12         return n==0;//first==null;
    13     }
    14     public int size()
    15     {
    16         return n;
    17     }
    18     
    19     public void push(T t)
    20     {
    21         Node<T> oldfirst=first;
    22         first=new Node<T>();
    23         first.t=t;
    24         first.next=oldfirst;
    25         n++;
    26         
    27     }
    28     
    29     public T pop()
    30     {
    31         if(isEmpty()) throw new NoSuchElementException("Stack underflow");
    32         T t=(T) first.t;
    33         first=first.next;
    34         n--;
    35         return t;
    36         
    37     }
    38     
    39      public T peek() {
    40             if (isEmpty()) throw new NoSuchElementException("Stack underflow");
    41             return (T) first.t;
    42         }
    43     
    44     
    45     
    46     @Override
    47      public String toString() {
    48             StringBuilder s = new StringBuilder();
    49             for ( T item : this) {
    50                 s.append(item);
    51                 s.append(' ');
    52             }
    53             return s.toString();
    54         }
    55     private class Node<T>
    56     {   T t;
    57         Node<T> next;
    58     }
    59     
    60     @Override
    61     public Iterator<T> iterator() {
    62        return new ListIterator(first);
    63     }
    64     
    65     private class ListIterator implements Iterator<T>
    66     {
    67          private Node<T> current;
    68          
    69          public  ListIterator(Node<T> first)
    70          {
    71              current=first;
    72          }
    73 
    74          @Override
    75         public boolean hasNext() {
    76             return (current!=null);
    77         }
    78 
    79         @Override
    80         public T next() {
    81           if(!hasNext())throw new NoSuchElementException("Stack underflow");
    82            T t=current.t;
    83            current=current.next;
    84            return t;
    85         }
    86         
    87     }
    88 
    89     
    90 }
    View Code

    队列实现:

     1 public class Queue<T> implements Iterable<T>{
     2     
     3     private Node<T> first;
     4     private Node<T> last;
     5     private int n;
     6     
     7     public Queue()
     8     {
     9         first=null;
    10         last=null;
    11         n=0;
    12     }
    13     
    14    public boolean isEmpty() {
    15             return first == null;
    16         }
    17    
    18    public int size() {
    19        return n;
    20    }
    21    
    22    public T peek() {
    23        if (isEmpty()) throw new NoSuchElementException("Queue underflow");
    24        return first.t;
    25    }
    26 
    27    public void enqueue(T t)
    28    {
    29        Node<T> oldlast=last;
    30        last=new Node<T>();
    31        last.t=t;
    32        last.next=null;
    33        if(isEmpty()) first=last;
    34        else
    35            oldlast.next=last;
    36        n++;
    37    }
    38    
    39    @Override
    40    public String toString() {
    41        StringBuilder s = new StringBuilder();
    42        for ( T item : this) {
    43            s.append(item);
    44            s.append(' ');
    45        }
    46        return s.toString();
    47    } 
    48    @Override
    49     public Iterator<T> iterator() {
    50     return new ListIterator(first);
    51     }
    52    private class ListIterator implements Iterator<T>
    53    {
    54        private Node<T> current;
    55        
    56      public ListIterator(Node<T> first)
    57      {
    58          current=first;
    59      }
    60     @Override
    61     public boolean hasNext() {
    62         return current!=null;
    63     }
    64 
    65     @Override
    66     public T next() {
    67         if (!hasNext()) throw new NoSuchElementException();
    68         T t=current.t;
    69         current=current.next;
    70         return t;
    71     }
    72        
    73    }
    74    public T dequeue()
    75    {
    76        if (isEmpty()) throw new NoSuchElementException("Queue underflow");
    77        T t=first.t;
    78        first=first.next;
    79        n--;
    80        if(isEmpty()) last=null;
    81        return null;
    82    }
    83     private static class Node<T>
    84     {
    85         private T t;
    86         private Node<T> next;
    87     }
    88     
    89     
    90     
    91 
    92 }
    View Code

     背包实现:

           //除了push()的名称更改为add()和删除 pop()之外,其实现与Stack.java相同

     1 public class Bag<T> implements Iterable<T> {
     2     private Node<T> first;
     3     private int n;
     4     
     5     public Bag()
     6     {
     7         first=null;
     8         n=0;
     9     }
    10     public boolean isEmpty()
    11     {
    12         return n==0;//first==null;
    13     }
    14     public int size()
    15     {
    16         return n;
    17     }
    18     
    19     public void add(T t)
    20     {
    21         Node<T> oldfirst=first;
    22         first=new Node<T>();
    23         first.t=t;
    24         first.next=oldfirst;
    25         n++;
    26         
    27     }
    28     
    29     
    30      public T peek() {
    31             if (isEmpty()) throw new NoSuchElementException("Stack underflow");
    32             return (T) first.t;
    33         }
    34     
    35     
    36     
    37     @Override
    38      public String toString() {
    39             StringBuilder s = new StringBuilder();
    40             for ( T item : this) {
    41                 s.append(item);
    42                 s.append(' ');
    43             }
    44             return s.toString();
    45         }
    46     private class Node<T>
    47     {   T t;
    48         Node<T> next;
    49     }
    50     
    51     @Override
    52     public Iterator<T> iterator() {
    53        return new ListIterator(first);
    54     }
    55     
    56     private class ListIterator implements Iterator<T>
    57     {
    58          private Node<T> current;
    59          
    60          public  ListIterator(Node<T> first)
    61          {
    62              current=first;
    63          }
    64 
    65          @Override
    66         public boolean hasNext() {
    67             return (current!=null);
    68         }
    69 
    70         @Override
    71         public T next() {
    72           if(!hasNext())throw new NoSuchElementException("Stack underflow");
    73            T t=current.t;
    74            current=current.next;
    75            return t;
    76         }
    77         
    78     }
    79 
    80     
    81 }
    View Code

         

  • 相关阅读:
    sqloraclesharePool 天高地厚
    aspx工作原理 天高地厚
    【转载】VB ActiveX插件开发打包部署一条龙服务 天高地厚
    【转载】为高负载网络优化Nginx和Node.js 天高地厚
    几个重要的基本概念 天高地厚
    Delphi中取得汉字的首字母
    C#中将字符串转换为MD5
    使用RDLC报表(一)
    在Delphi中的TreeView中保存多个数据
    C#中将图片文件存至数组
  • 原文地址:https://www.cnblogs.com/lls101/p/11187126.html
Copyright © 2011-2022 走看看