聲明
本文是博主在Coursera學習時所寫的學習筆記,如有錯誤疏漏還望各位指正。
歡迎交流討論
如果大家轉載,請註明本文地址!
Stacks
簡介
- 棧是限定僅在表頭進行插入和刪除操作的線性表。其限制是僅允許在表的一端進行插入和刪除運算。
- 課程中以存儲String的棧爲例
屬性
public StackOfStrings
函數 功能 StackOfStrings() 構造函數 void push(String item) 向棧中添加一個元素 String pop() 刪除並返回棧頂元素 boolean isEmpty() 返回棧是否爲空 int size() 棧裏有多少元素 最後一個屬性可有可無,其餘屬性是棧必需的
實現方法
用鏈表表示
原理 :
- 始終保持指向鏈表的第一個節點。對第一個節點進行刪除/插入
- push(): 創建一個新節點,使之指向原來的棧頂,並使之成爲棧頂
- pop(): 刪除棧頂節點,使其相鄰節點成爲棧頂節點
代碼實現
分析
- 時間複雜度:每個操作的時間複雜度是常數
內存: 含N個元素的棧佔用內存約
40N bytes(棧所佔用的內存,不包括字符串的內存)
數組表示
原理
- 使用數組s[]來存儲元素
- push(): 給s[N]賦值
- pop(): 刪除s[N-1]
代碼實現
可變長的數組表示
原理
- push():數組長度 +1
- pop() :數組長度 -1
實現
每次創建一個新數組,長度加/減一,並將原來數組拷貝到新數組
這樣時間複雜度爲1+2+3+...+N ~N22
我們可以試着改進:
每次數組滿的時候,創建一個大小爲原來兩倍的數組並拷貝,
這樣時間複雜度爲:N+2+4+...+N ~3N
其中第一個N是每次操作都需要訪問數組一次代碼實現
示例代碼一
public class LinkedStackOfStrings
{
private Node first = null;
//私有內部類
private class Node
{
String item;
Node next;
}
public boolean isEmpty()
{
return first == null;
}
public void push(String item)
{
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
}
public String pop()
{
String item = first.item;
first = first.next;
return item;
}
}
示例代碼三
public class FixedCapacityStackOfStrings
{
private String[] s;
private int N = 0;
public FixedCapacityStackOfStrings(int capacity)
{
s = new String[capacity];
}
public boolean isEmpty()
{
return N == 0;
}
public void push(String item)
{
s[N++] = item;
}
public String pop()
{
s[--N];
}
}
示例代碼三
public class ResizingArrayStackOfStrings
{
private String[] s;
private int N = 0;
public ResizingArrayStackOfStrings()
{
s = new String[1];
}
public boolean isEmpty()
{
return N == 0;
}
public void push(String item)
{
if (N == s.length)
resize(2 * s.length);
s[N++] = item;
}
public String pop()
{
s[--N];
}
private void resize(int capacity)
{
String[] copy = new String[capacity];
for (int i = 0; i < N; i++)
copy[i] = s[i];
s = copy;
}
}
Queue
簡介
在隊列這種數據結構中,最先插入在元素將是最先被刪除;反之最後插入的元素將最後被刪除,因此隊列又稱爲“先進先出”(FIFO—first in first out)的線性表。
屬性
public class QueueOfStrings
函數 功能 QueueOfStrings() 創建一個新隊列 void enqueue(String item) 向隊列中插入一個新元素 String dequeue() 刪除並返回隊列中最先插入的元素 boolean isEmpty() 判斷隊列是否爲空 int size() - 返回隊列中元素的個數 *
除最後一個其餘的屬性都是隊列所必需的
代碼實現
public class LinkedQueueOfStrings
{
private Node first, last;
private class Node
{
String item;
Node next;
}
public boolean isEmpty()
{
return first == null;
}
public void enqueue(String item)
{
Node oldlast = last;
last = new Node();
last.item = item;
last.next = null;
if (isEmpty()) first = last;
else oldlast.next = last;
}
public String dequeue()
{
String item = first.item;
first = first.next;
if (isEmpty()) last = null;
return item;
}
}
刪除和插入函數與棧有些不同,需要對隊列爲空的情況進行特殊處理
應用
棧和隊列在計算機中有許多的應用,棧可以用計算算術表達式,隊列和與用於廣度優先遍歷二叉樹,有興趣的朋友可以試一下。