總結學習棧與隊列

棧和隊列都是特殊的線性表,對線性表的插入與刪除操作位置進行了限定。棧是一種先進後出的數據結構,只能在棧頂進行插入與刪除;隊列是一種先進先出的數據結構,只能在隊尾查入隊頭刪除。
與線性表一樣,棧和隊列都可以分別用順序存儲和鏈式存儲的形式實現。
1.棧的順序存儲結構實現
設置空棧標誌爲棧頂指針top=-1,入棧top+1,出棧top-1。
template
class SeqStack
{
public:
SeqStack( ); //構造函數,初始化一個空棧
~SeqStack( ); //析構函數
void Push( DataType x ); //入棧操作,將元素x入棧
DataType Pop( ); //出棧操作,將棧頂元素彈出
DataType GetTop( ); //取棧頂元素(並不刪除)
int Empty( ); //判斷棧是否爲空
private:
DataType data[StackSize]; //存放棧元素的數組
int top; //遊標,棧頂指針,爲棧頂元素在數組中的下標
};
(1)入棧push
template
void SeqStack :: Push(DataType x)
{
if (top == StackSize - 1) throw “上溢”;
data[++top] = x;
}
(2)出棧pop
template
DataType SeqStack :: Pop( )
{
DataType x;
if (top == -1) throw “下溢”;
x = data[top–];
return x;
}
構造函數和析構函數與線性表的實現並沒有太大差異,不作贅述。
2.棧的鏈式存儲結構實現
首先定義節點
template
struct Node
{
DataType data;
Node*next;
};
template
class LinkStack
{
public:
LinkStack( ); //構造函數,初始化一個空鏈棧
~LinkStack( ); //析構函數,釋放鏈棧各結點的存儲空間
void Push(DataType x); //入棧操作,將元素x入棧
DataType Pop( ); //出棧操作,將棧頂元素出棧
DataType GetTop( ); //取棧頂元素(並不刪除)
int Empty( ); //判空操作,判斷鏈棧是否爲空棧
private:
Node *top; //棧頂指針即鏈棧的頭指針
};
(1)入棧push
template
void LinkStack :: Push(DataType x)
{
Node *s = nullptr;
s = new Node; s->data = x; //申請結點s數據域爲x
s->next = top; top = s; //將結點s插在棧頂
}
(2)出棧pop
template
DataType LinkStack :: Pop( )
{
Node *p = nullptr;
DataType x;
if (top == nullptr) throw “下溢”;
x = top->data; p = top; //暫存棧頂元素
top = top->next; //將棧頂結點摘鏈
delete p;
return x;
}
3.隊列的順序結構存儲實現
爲了更好的利用內存空間,我們使用循環隊列實現隊列的順序存儲。並且同時設置隊首rear和隊尾front指針,通過取模實現邏輯上的循環。即隊滿標誌爲(rear+1)%QueueSize=front,其中QueueSize爲構建隊列時申請的數組大小。隊空的標誌爲rear=front。
const int QueueSize = 100; //100是示例性數據,根據需要重新定義
template //定義模板類CirQueue
class CirQueue
{
public:
CirQueue( ); //構造函數,初始化空隊列
~ CirQueue( ); //析構函數
void EnQueue(DataType x); //入隊操作,將元素x入隊
DataType DeQueue( ); //出隊操作,將隊頭元素出隊
DataType GetQueue( ); //取隊頭元素(並不刪除)
int Empty( ); //判斷隊列是否爲空
private:
DataType data[QueueSize]; //存放隊列元素的數組
int front, rear; //遊標,隊頭和隊尾指針
};
(1)構造函數
設置rear=front=QueueSize-1,一般在數組的高端。
(3)入隊enqueue
template
void CirQueue :: EnQueue(DataType x)
{
if ((rear + 1) % QueueSize == front)
throw “上溢”;
rear = (rear + 1) % QueueSize; //隊尾指針在循環意義下加1
data[rear] = x; //在隊尾處插入元素
}
(4)出隊dequeue
template
DataType CirQueue :: DeQueue( )
{
if (rear == front) throw “下溢”;
front = (front + 1) % QueueSize; //隊頭指針在循環意義下加1
return data[front]; //讀取並返回出隊前的隊頭元素
}
4.隊列的鏈式存儲結構實現
struct Node
{
DataType data; //數據域
Node *next; //指針域
};

template
class LinkQueue
{
public:
LinkQueue( ); //構造函數,初始化一個空的鏈隊列
~LinkQueue( ); //析構函數,釋放鏈隊列各結點的存儲空間
void EnQueue(DataType x); //入隊操作,將元素x入隊
DataType DeQueue( ); //出隊操作,將隊頭元素出隊
DataType GetQueue( ); //取鏈隊列的隊頭元素
int Empty( ); //判斷鏈隊列是否爲空
private:
Node *front, *rear; //隊頭和隊尾指針,分別指向頭結點和終端結點
};
(1)入隊enqueue
template
void LinkQueue :: EnQueue(DataType x)
{
Node *s = nullptr;
s = new Node; //申請結點s
s->data = x; s->next = nullptr;
rear->next = s; rear = s; //將結點s插入到隊尾
}
(2)出隊dequeue
template
DataType LinkQueue :: DeQueue( )
{
DataType x;
Node *p = nullptr;
if (rear == front) throw “下溢”;
p = front->next; x = p->data; //暫存隊頭元素
front->next = p->next; //將隊頭元素所在結點摘鏈
if (p->next == nullptr) rear = front; //判斷出隊前隊列長度是否爲1
delete p;
return x;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章