實驗四 棧和佇列的定義與實現(未完成)
阿新 • • 發佈:2019-02-17
一、 實驗目的:
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;
}
}