四,栈和队列
 栈
栈只允许访问一个数据项:即最后插入的数据项.移出这个数据项后才能访问倒数第二个插入的数据项,
以此类推.这种机制在不少编程环境中都很有用.
大部分微处理器运用基于栈的体系结构.当调用一个方法时,把它的返回地址和参数压入栈,当方法结束
返回时,那些数据出栈.栈操作就嵌入在微处理器中.
 
 package stack;
package stack;

 import java.io.*;
import java.io.*;


 /** *//**
/** *//**
 *
 * 
 * @author jason
 * @author jason
 *
 * 
 */
 */

 class StackC
class StackC  {
{
 private int maxSize;
 private int maxSize;

 private char[] stackArray;
 private char[] stackArray;

 private int top;
 private int top;

 // --------------------------------------------------------------
 // --------------------------------------------------------------
 public StackC(int max) // constructor
 public StackC(int max) // constructor

 
  {
{
 maxSize = max;
  maxSize = max;
 stackArray = new char[maxSize];
  stackArray = new char[maxSize];
 top = -1;
  top = -1;
 }
 }

 // --------------------------------------------------------------
 // --------------------------------------------------------------
 public void push(char j) // put item on top of stack
 public void push(char j) // put item on top of stack

 
  {
{
 stackArray[++top] = j;
  stackArray[++top] = j;
 }
 }

 // --------------------------------------------------------------
 // --------------------------------------------------------------
 public char pop() // take item from top of stack
 public char pop() // take item from top of stack

 
  {
{
 return stackArray[top--];
  return stackArray[top--];
 }
 }

 // --------------------------------------------------------------
 // --------------------------------------------------------------
 public char peek() // peek at top of stack
 public char peek() // peek at top of stack

 
  {
{
 return stackArray[top];
  return stackArray[top];
 }
 }

 // --------------------------------------------------------------
 // --------------------------------------------------------------
 public boolean isEmpty() // true if stack is empty
 public boolean isEmpty() // true if stack is empty

 
  {
{
 return (top == -1);
  return (top == -1);
 }
 }
 // --------------------------------------------------------------
 // --------------------------------------------------------------
 } // end class StackX
} // end class StackX
 // //////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////


 class Reverser
class Reverser  {
{
 private String input; // input string
 private String input; // input string

 private String output; // output string
 private String output; // output string

 // --------------------------------------------------------------
 // --------------------------------------------------------------

 public Reverser(String in) // constructor
 public Reverser(String in) // constructor

 
  {
{
 input = in;
  input = in;
 }
 }

 // --------------------------------------------------------------
 // --------------------------------------------------------------
 public String doRev() // reverse the string
 public String doRev() // reverse the string

 
  {
{
 int stackSize = input.length(); // get max stack size
  int stackSize = input.length(); // get max stack size
 StackC theStack = new StackC(stackSize); // make stack
  StackC theStack = new StackC(stackSize); // make stack


 for (int j = 0; j < input.length(); j++)
  for (int j = 0; j < input.length(); j++)  {
{
 char ch = input.charAt(j); // get a char from input
   char ch = input.charAt(j); // get a char from input
 theStack.push(ch); // push it
   theStack.push(ch); // push it
 }
  }
 output = "";
  output = "";

 while (!theStack.isEmpty())
  while (!theStack.isEmpty())  {
{
 char ch = theStack.pop(); // pop a char,
   char ch = theStack.pop(); // pop a char,
 output = output + ch; // append to output
   output = output + ch; // append to output
 }
  }
 return output;
  return output;
 } // end doRev()
 } // end doRev()
 // --------------------------------------------------------------
 // --------------------------------------------------------------
 } // end class Reverser
} // end class Reverser
 // //////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////


 class ReverseApp
class ReverseApp  {
{

 public static void main(String[] args) throws IOException
 public static void main(String[] args) throws IOException  {
{
 String input, output;
  String input, output;

 while (true)
  while (true)  {
{
 System.out.print("Enter a string: ");
   System.out.print("Enter a string: ");
 System.out.flush();
   System.out.flush();
 input = getString(); // read a string from kbd
   input = getString(); // read a string from kbd
 if (input.equals("")) // quit if [Enter]
   if (input.equals("")) // quit if [Enter]
 break;
    break;
 // make a Reverser
   // make a Reverser
 Reverser theReverser = new Reverser(input);
   Reverser theReverser = new Reverser(input);
 output = theReverser.doRev(); // use it
   output = theReverser.doRev(); // use it
 System.out.println("Reversed: " + output);
   System.out.println("Reversed: " + output);
 } // end while
  } // end while
 } // end main()
 } // end main()

 // --------------------------------------------------------------
 // --------------------------------------------------------------


 public static String getString() throws IOException
 public static String getString() throws IOException  {
{
 InputStreamReader isr = new InputStreamReader(System.in);
  InputStreamReader isr = new InputStreamReader(System.in);
 BufferedReader br = new BufferedReader(isr);
  BufferedReader br = new BufferedReader(isr);
 String s = br.readLine();
  String s = br.readLine();
 return s;
  return s;
 }
 }
 // --------------------------------------------------------------
 // --------------------------------------------------------------
 } // end class ReverseApp
} // end class ReverseApp
 // //////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////

 
上面的这个例子就是栈的应用,给定一个字符串按照倒排的顺序重新输出。
栈的效率
在实现栈的类中,数据项入栈和出栈的时间复杂度都为常数O(1).这也就是说,栈操作所耗的时间不依
赖于栈中数据项的个数,因此操作时间短。栈不需要比较和移动操作。
队列
队列(queue),队列是一种数据结构,有点类似栈,只是在队列中第一个插入的数据项也会最先被移出
(先进先出,FIFO),而在栈中,最后插入的数据项最先移出(LIFO)
队列的代码:
 package queue;
package queue;

 /** *//**
/** *//**
 *
 * 
 * @author jason
 * @author jason
 *
 *
 */
 */
 class Queue
class Queue


 {
{
 private int maxSize;
private int maxSize;
 private long[] queArray;
private long[] queArray;
 private int front;
private int front;
 private int rear;
private int rear;
 private int nItems;
private int nItems;
 //--------------------------------------------------------------
//--------------------------------------------------------------
 public Queue(int s)          // constructor
public Queue(int s)          // constructor

 
    {
{
 maxSize = s;
   maxSize = s;
 queArray = new long[maxSize];
   queArray = new long[maxSize];
 front = 0;
   front = 0;
 rear = -1;
   rear = -1;
 nItems = 0;
   nItems = 0;
 }
   }
 //--------------------------------------------------------------
//--------------------------------------------------------------
 public void insert(long j)   // put item at rear of queue
public void insert(long j)   // put item at rear of queue

 
    {
{
 if(rear == maxSize-1)         // deal with wraparound
   if(rear == maxSize-1)         // deal with wraparound
 rear = -1;
      rear = -1;
 queArray[++rear] = j;         // increment rear and insert
   queArray[++rear] = j;         // increment rear and insert
 nItems++;                     // one more item
   nItems++;                     // one more item
 }
   }
 //--------------------------------------------------------------
//--------------------------------------------------------------
 public long remove()         // take item from front of queue
public long remove()         // take item from front of queue

 
    {
{
 long temp = queArray[front++]; // get value and incr front
   long temp = queArray[front++]; // get value and incr front
 if(front == maxSize)           // deal with wraparound
   if(front == maxSize)           // deal with wraparound
 front = 0;
      front = 0;
 nItems--;                      // one less item
   nItems--;                      // one less item
 return temp;
   return temp;
 }
   }
 //--------------------------------------------------------------
//--------------------------------------------------------------
 public long peekFront()      // peek at front of queue
public long peekFront()      // peek at front of queue

 
    {
{
 return queArray[front];
   return queArray[front];
 }
   }
 //--------------------------------------------------------------
//--------------------------------------------------------------
 public boolean isEmpty()    // true if queue is empty
public boolean isEmpty()    // true if queue is empty

 
    {
{
 return (nItems==0);
   return (nItems==0);
 }
   }
 //--------------------------------------------------------------
//--------------------------------------------------------------
 public boolean isFull()     // true if queue is full
public boolean isFull()     // true if queue is full

 
    {
{
 return (nItems==maxSize);
   return (nItems==maxSize);
 }
   }
 //--------------------------------------------------------------
//--------------------------------------------------------------
 public int size()           // number of items in queue
public int size()           // number of items in queue

 
    {
{
 return nItems;
   return nItems;
 }
   }
 //--------------------------------------------------------------
//--------------------------------------------------------------
 }  // end class Queue
}  // end class Queue
 ////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
 class QueueApp
class QueueApp


 {
{
 public static void main(String[] args)
public static void main(String[] args)

 
    {
{
 Queue theQueue = new Queue(5);  // queue holds 5 items
   Queue theQueue = new Queue(5);  // queue holds 5 items

 theQueue.insert(10);            // insert 4 items
   theQueue.insert(10);            // insert 4 items
 theQueue.insert(20);
   theQueue.insert(20);
 theQueue.insert(30);
   theQueue.insert(30);
 theQueue.insert(40);
   theQueue.insert(40);

 theQueue.remove();              // remove 3 items
   theQueue.remove();              // remove 3 items
 theQueue.remove();              //    (10, 20, 30)
   theQueue.remove();              //    (10, 20, 30)
 theQueue.remove();
   theQueue.remove();

 theQueue.insert(50);            // insert 4 more items
   theQueue.insert(50);            // insert 4 more items
 theQueue.insert(60);            //    (wraps around)
   theQueue.insert(60);            //    (wraps around)
 theQueue.insert(70);
   theQueue.insert(70);
 theQueue.insert(80);
   theQueue.insert(80);

 while( !theQueue.isEmpty() )    // remove and display
   while( !theQueue.isEmpty() )    // remove and display

 
       {                            //    all items
{                            //    all items
 long n = theQueue.remove();  // (40, 50, 60, 70, 80)
      long n = theQueue.remove();  // (40, 50, 60, 70, 80)
 System.out.print(n);
      System.out.print(n);
 System.out.print(" ");
      System.out.print(" ");
 }
      }
 System.out.println("");
   System.out.println("");
 }  // end main()
   }  // end main()
 }  // end class QueueApp
}  // end class QueueApp
 ////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////


 
队列的效率
和栈一样,队列中插入数据项和移出数据项的时间复杂度均为 O(1).
双端队列
双端队列就是一个两端都是结尾的对列。队列的每一个端都可以插入数据项和移出数据项。这些方法可
以叫作insertLeft()和insertRight(),以及removeLeft()和removeRight().
如果严禁调用insertLeft()和removeLeft()方法(或禁用右端的操作),双端队列功能就和栈一样。禁
止调用insertLeft()和removeLeft()方法(或相反的另一对方法),他的功能就和队列一样了。
双端队列与栈或队列相比,是一种多用途的数据结构,在容器类库中有时会用双端队列来提供栈和队列
的两种功能。但是,双端队列 不像栈和队列那常用。
优先级队列
优先级队列是比栈和队列更专用的数据结构。但它在很多情况下都很有用。像普通队列一样,优先级队
列有一个对头和一个队尾,并且也是从对头移出数据项。不过在优先级队列中,数据项按关键字的值有
序,这样关键字最小的数据项(或者在某些实现中是关键最大的数据项)总是在队列头。数据项插入的
时候会按照顺序插入到合适的位置以确保队列的顺序。
优先级队列的效率
优先级队列插入操作需要时间O(N)的时间,而删除操作则需要O(1)的时间。