1. 程式人生 > >實驗四 棧和佇列的定義與實現(未完成)

實驗四 棧和佇列的定義與實現(未完成)

一、 實驗目的:
1. 深入瞭解棧的儲存結構和運算特點。
2. 熟練掌握棧的基本運算。
3. 深入瞭解佇列的特性。
4. 掌握佇列的兩種儲存結構和運算方法。
二、 實驗內容:
1. 棧:
分別使用順序棧和鏈棧各完成以下棧的應用之一。
(1) 括號匹配問題。判斷一個表示式中所含有多種括號是否匹配。
(2) 判斷迴文。 判斷一個字串的內容是否是迴文
(3) 數制轉換問題。將一個十進位制數轉換為十六進位制形式輸出。
例:26 轉換為 1A
(4) 大數加法問題。將兩個用字串表示的大數,進行加法運算,並儲存為和字串。
2. 佇列:
(1) 分別實現佇列的順序儲存結構(迴圈佇列),佇列的鏈式儲存結構。
(2) (選做)運用佇列實現列印楊輝三角。
(1) 括號匹配問題。判斷一個表示式中所含有多種括號是否匹配。


使用順序棧解決:
介面Istack:

介面Istack:
package ch03;
public interface Istack
{
        public void clear();         //將一個已經存在的棧置為空
        public boolean isEmpty();//判斷棧是否為空
        public int length();        //返回棧中個數據元素的個數
        public  Object peek();
                            //讀取棧項元素,若棧為空,則返回為空
        public
void push(Object x) throws Exception; //入棧:將資料元素壓入棧頂 public Object pop(); //出棧:刪除並返回棧頂元素 }

順序棧SqStack:

package ch03;
public class SqStack implements Istack
{
        private Object[]stackElem;  //物件陣列
        private int top;
        //如果棧為空,top=0,否則表示棧頂元素的下一個儲存位置
//構造方法,構造一個儲存空間容量為k的空棧 public SqStack(int k) { top = 0; stackElem = new Object[k]; } //棧置空 public void clear() { top = 0; } //判斷棧是否為空 public boolean isEmpty() { return top == 0; } //求棧中資料元素的個數 public int length() { return top; } //取棧頂元素 public Object peek() { if(!isEmpty()) { return stackElem[top-1]; } else return null; } //入棧 public void push(Object x) throws Exception { if(top == stackElem.length) throw new Exception("棧已滿!"); else stackElem[top++]= x; } //出棧 public Object pop() { if(isEmpty()) return null; else return stackElem[--top]; /* { top = top-1; return stackElem[top]; }*/ } public void display() { for(int i = top-1;i>=0;i--) System.out.print(stackElem[top].toString()+" "); } }

測試類Example1.java:

package ch03;
import java.util.Scanner;
public class Example1
{
        private final int LEFT = 0;
        private final int RIGHT = 1;
        private final int OTHER = 2;

        //判斷括號型別
        public int verifyFlag(String str)
        {
    if("(".equals(str)||"[".equals(str)||"{".equals(str)||"/*".equals(str))
        return LEFT;
        else if(")".equals(str)||"[".equals(str)||"{".equals(str)||"*/".equals(str))
        return RIGHT;
        else 
        return OTHER;
    }

    //檢驗左括號與右括號是否匹配
    public boolean match(String str1,String str2)
    {
    if("(".equals(str1)&&")".equals(str2)||"[".equals(str1)&&"]".equals(str2)||"{".equals(str1)&&"}".equals(str2)||"/*".equals(str1)&&"*/".equals(str2))
        return true;
        else
        return false;
    }

    private boolean isLegal(String str) throws Exception
    {
        if(!"".equals(str)&&str!=null)
        {
            SqStack S = new SqStack(100);
            int length = str.length();
            for(int i=0;i<length;i++)
            {
                char c = str.charAt(i);
                String t = String.valueOf(c);
                if(i!= length)
                {
                    if(('/') == c && '*' == str.charAt(i + 1) ||('*'==c && '/'==str.charAt(i+1)))
                    {
                        t = t.concat(String.valueOf(str.charAt(i+1)));
                        ++i;
                    }
                }
                if(LEFT == verifyFlag(t))
                {
                    S.push(t);
                }
                else if (RIGHT == verifyFlag(t))
                {
                    if(S.isEmpty()||!match(S.pop().toString(),t))
                    {
                        throw new Exception("錯誤!Java語句不合法!!!");
                    }
                }
            }
            if(!S.isEmpty())
            throw new Exception("錯誤:java 語句不合法!");
            return true;
        }
        else 
            throw new Exception("錯誤;java 語句為空!");
    }

    public static void main(String []args) throws Exception
    {
        Example1 e1 = new Example1();
        System.out.println("請輸入分Java語句:");
        Scanner sc = new Scanner(System.in);
        if(e1.isLegal(sc.nextLine()))
        System.out.println("java語句合法!");
        else
        System.out.println("錯誤!Java語句不合法!");
    }
}

執行結果:
這裡寫圖片描述

(2) 判斷迴文。 判斷一個字串的內容是否是迴文

//判斷字元序列是否為迴文序列,若是則返回true,否則返回false;
        public Boolean isPalindSeq(String str)
        {
            LinkStack S = new LinkStack();
            int i = 0;
            for(i = 0;i< str.length;i++)
            {   
                S.push(str.charAt(i));
                char c = ((Character)S.pop().charValue();
                if(c!=str.charAt(i))
                return false;
            }
                return true;
        }

(4) 使用鏈棧解決大數加法問題

介面Istack:

package ch01;
public interface Istack
{
        public void clear();            //將一個已經存在的棧置為空
        public boolean isEmpty();               //判斷棧是否為空
        public int length();            //返回棧中個數據元素的個數
        public  Object peek();
                            //讀取棧項元素,若棧為空,則返回為空
        public void push(Object x) throws Exception;
                                        //入棧:將資料元素壓入棧頂
        public Object pop();            //出棧:刪除並返回棧頂元素  
}

結點類Node:

package ch01;
public class Node
{
    public Object data;
        public Node next;

        public Node()
        {
            this(null,null);
        }

        public Node(Object data)
        {
            this(data,null);
        }

        public Node(Object data,Node next)
        {
            this.data = data;
            this.next = next;
        }
}

鏈棧LinkStack:

package ch01;
public class LinkStack implements Istack
{
        private Node top;

        public void clear()
        {
            top = null;
        }   

        public boolean isEmpty()
        {
            return top == null;
        }

        public int  length()
        {
            Node p = top;
            int length = 0;
            while(p != null)
            {
                p = p.next;
                ++length;
            }
            return length;
        }

        //取棧頂元素並返回其值
        public Object peek()
        {
            if(!isEmpty())
                return top.data;
            else
                return null;
        }

        //入棧
        public void push(Object x)
        {
            Node p = new Node(x);
            p.next = top;
            top = p;
        }

        //出棧
        public Object pop()
        {
            if(isEmpty())
            {
                return null;
            }
            else
            {
                Node p = top;
                top = top.next;
                return p.data;
            }
        }

        public void display()
        {
            Node p = top;
            while(p!= null)
            {
                System.out.println((p.data.toString() + " "));
                p = p.next;
            }
        }
}

Example2:

package ch03;
public class Example2
{
        public String add(String a,String b) throws Exception
        {
            LinkStack sum = new LinkStack();
            LinkStack sA = numSplit(a);
            LinkStack sB = numSplit(b);
            int Sum;
            boolean isCarry = false;
            while(!sA.isEmpty()&&!sB.isEmpty())
            {
                Sum = (Integer)sA.pop() + (Integer)sB.pop();
                if(isCarry)
                {
                    Sum ++;
                    isCarry = false;
                }
                if(Sum>=10)
                {
                    Sum =Sum-10;
                    sum.push(Sum);
                    isCarry = ture;
                }
                else
                {
                    sum.push(Sum);
                }
            }
            LinkStack temp = !sA.isEmpty()?sA:sB;
            while(!temp.isEmpty())
            {
                if(isCarry)
                {
                    int t = (Integer)temp.pop();
                    ++t;
                    if(t>=10)
                    {
                        t = t-10;
                        sum.ppush(t);
                    }
                    else
                    {
                        sum.push(t);
                        isCarry = false;
                    }
                }
                else
                    sum.push(temp.pop());
            }
            if(isCarry)
            {
                sum.push(1);
            }
            String str = new String();
            while(!sum.isEmpty())
            str = str.concat(sum.pop().toString());
            return str;
        }

        public LinkStack numSplit(String str) throws Exception
        {
            LinkStack s = new LinkStack();
            for(int i=0;i<str.length();i++)
            {
                char c = str.charAt(i);
                if(' ' == c)
                    continue;
                else if('0'<= c &&'9'>=c)
                    s.push(Integer.valueOf(String.valueOf(c)));
                else
                throw new Exception("錯誤:輸入了非數字型字元");
            }
            return s;
        }

        public static void main(String []args) throws Exception
        {
            Example2 e = new Example2();
            System.out.println("兩個大數的和:"+       e.add("12345678","12345678"));
         }
    }

佇列的順序儲存結構如下:
介面:IQueue

public interface IQueue
{
    public void clear();                                //將佇列置為空佇列
    public boolean isEmpty();                       //判斷佇列是否為空
    public int length();                    //返回隊中中中資料元素的個數
    public Object peek();                       //讀取隊首元素並返其值
    public void offer(Object x ) throws Exception;
                                    //將資料元素x插入使其成為新的隊尾元素
    public Object poll();
                        //刪除隊首元素並返回其值,若佇列為空,則返回為空
}

定義類CircleSqQueue實現介面:

public class CircleSqQueue implements IQueue
{
    private Object[]Elem;
    private int front ;                                     //隊首元素
    private int rear;           //隊尾不空,指向隊尾元素的下一個儲存空間

    //構造方法
    public CircleSqQueue(int maxSize)
    {
        front = rear = 0;
        Elem = new Object[maxSize];
    }

    public void clear()
    {
        front  = rear = 0;
    }   

    public boolean isEmpty()
    {
        return front  == rear ;
    }

    public int length()
    {
        return (rear -front+Elem.length)%Elem.length;
    }

    public Object peek()
    {
        if(front  == rear )
            return null;
        else 
            return Elem[front];
    }

    public void offer (Object x) throws Exception
    {
        if((rear +1 )%Elem.length == front )
        throw new Exception("佇列已滿!");
        else
        {
            Elem[rear]  = x;
            rear =(rear + 1) % Elem.length;
        }
    }
    public Object poll()
    {
        if(front == rear)
            return null;
        else
        {
            Object t = Elem[front];
            front = (front + 1) % Elem.length;
            return t;
        }
    }
    public void display()
    {
        if(!isEmpty())
        {
            for(int i = front;i!=rear; i = (i+1)%Elem.length)
                System.out.println(Elem[i].toString() + " ");
        }
        else 
            System.out.println("此佇列為空!");
    }
}

佇列的鏈式儲存結構如下:
結點類Node:

package ch01;
public class Node
{
    public Object data;
    public Node next;

    public Node (Object data,Node next)
    {
        this.data = data;
        this.next = next;
    }

    public Node()
    {
        this(null,null);
    }

    public Node(Object data)
    {
        this(data,null);
    }
}

IQueue介面:

package ch01;
public interface IQueue
{
    public void clear();                                //將佇列置為空佇列
    public boolean isEmpty();                       //判斷佇列是否為空
    public int length();                    //返回隊中中中資料元素的個數
    public Object peek();                       //讀取隊首元素並返其值
    public void offer(Object x ) throws Exception;
                                    //將資料元素x插入使其成為新的隊尾元素
    public Object poll();
                        //刪除隊首元素並返回其值,若佇列為空,則返回為空
}

LinkQueue類:

package ch01;
import ch01.Node;
public class LinkQueue implements IQueue
{
    private Node front;
    private Node rear;

    public LinkQueue()
    {
        front = rear = null;
    } 

    public void clear()
    {
        front =rear = null;
    }

    public boolean isEmpty()
    {
        return front == null;
    }

    public int length ()
    {
        Node p = front;
        int length = 0;
        while(p != null)
        {
            p = p.next;
            ++length;
        }
        return length;
    }

    public Object peek()
    {
        if(front != null)
           return front.data;
        else
          return null;
    }

    public void offer(Object x)
    {
        Node p = new Node(x);
        if(front!=null)
        {
            rear.next = p;
            rear = p;
        }
        else 
            front = rear = p;
    }

    public Object poll()
    {
        if(front != null)
        {
            Node p = front;
            front =front.next;
            if(p == rear)
                    rear = null;
            return p.data;
        }
        else
                return null;
    }
}