數據結構與算法分析
棧模型
- 限制插入和刪除只能在表的末端的表
- 表的末端叫做棧頂(top)
- 支持Push進棧和Pop入棧操作
- //LIFO后進先出表
棧的實現
鏈表實現
類型聲明
struct Node ;
typedef struct Node *PtrToNode ;
typedef struct Node Stack
int IsEmpty(Stack S) ;
Stack CreateStack(void) ;
void DisposeStack(Stack S) ;
void MakeEmpty(Stack S) ;
void Push(ElementType X,Stack S) ;
ElementType Top(Stack S) ;
void Pop(Stack s) ;
struct Node
{
ElementType Element ;
PtrToNode Next ;
}
檢測是否為空棧
void IsEmpty(Stack S)
{
return S->Next == NULL ;
}
創建空棧
Stack CreateStack(void)
{
Stack S ;
S = malloc(sizeof(struct Node)) ;
if(S == NULL)
{
FatalError("內存不足") ;
}
S->Next = NULL ;
MakeEmpty(S) ;
return S ;
}
void MakeEmpty(Stack S)
{
if(S == NULL)
{
Error("請先創建一個棧") ;
}
else
{
while(!IsEmpty(S)
Pop(S) ;
}
}
Push進棧
void Push(ElementType X, Stack S)
{
PtrToNode TmpCell ;
TmpCell = malloc(sizeof(struct Node)) ;
if(TmpCell == NULL)
FaltalError("內存不足") ;
else
{
TmpCell->Element = X ;
TmpCell->Next = S->Next ;
S->Next = TmpCell ;
}
}
返回top棧頂元素
ElementType Top(Stack S)
{
if(!IsEmpty(S)
return S->Next->ElementType ;
Error("空棧") ;
return 0 ;
}
Pop出棧
void Pop(Stack S)
{
PtrToNode FirstCell ;
FirstCell = S->Next ;
S->Next = FirstCell->Next ;
free(FirstCell) ;
}
數組實現
- 潛在危害:需要提前聲明棧的大小
- 實現思路:
- 棧指針TopOfStack //並不是指針,只是指示下標
- 壓棧Stack[TopOfStack] = x TopOfStack++ ;
- 出棧,TopOfStack-- ;
棧的聲明
struct StackRecord ;
typedef struct StackRecord *Stack ;
int IsEmpty(Stack S) ;
Stack CreateStack(int MaxElements) ;
void DisposeStack(Stack S) ;
void MakeEmpty(Stack S) ;
void Push(ElementType X,Stack S) ;
ElementType Top(Stack S) ;
void Pop(Stack s) ;
define EmptyTOS(-1) ; //空棧標志 加#
define MinStackSize (5) ;
struct Node
{
ElementType *Array ;
int Capacity ;
int TopOfStack ;
}
棧的創建//數組實現
Stack CreateStack(int MaxElements)
{
Stack S ;
if(MaxElements < MinStackSize)
Error("棧過小") ;
S = malloc(sizeof(struct Node) ;
if(S == NULL)
FatalError("內存不足") ;
S->Array = malloc(sizeof(struct Node) * MaxElements) ;
if(S->Array = NULL)
FatalError("內存不足") ;
S->Capacity = MaxElements ;
MakeEmpty(S) ;
}
void MakeEmpty(Stack S)
{
S->TopOfStack = EmptyTOS ;
}
釋放棧函數
void DisposeStack(Stack S)
{
if(S != NULL)
{
free(S->Array) ;
free(S) ;
}
}
檢測空棧函數
void IsEmpty(Stack S)
{
return S->TopOfStack == EmptyTOS ;
}
釋放棧函數
void Dispose(Stack S)
{
if(S != NULL)
{
free(S->Array) ;
free(S) ;
}
}
壓棧函數
void Push(ElementType X, Stack S)
{
if(IsFull(S))
Error("棧滿了") ;
else
S->Array[++S->TopOfStack] = X ;
}
返回棧頂函數
ElementType Top(Stack S)
{
if(!IsEmpty(S))
return S->Array[S->TopOfStack]
Error("空棧") ;
return 0 ;
}
出棧函數
void Pop(Stack S)
{
if(IsEmpty(S))
Error("空棧") ;
S->TopOfStack-- ;
}
棧的應用
- 平衡符號
- 后綴表達式
- 中綴表達式->后綴表達式
- 函數調用
隊列模型
- Enqueue入隊 在表的末端插入一個元素
- Dequeue出隊 返回或者刪除表的開頭的元素
- FIFO先進先出
隊列的實現
數組實現
注意問題:數組浪費為題
解決:循環數組
隊列的類型聲明
struct QueueRecord ;
typedef struct QueueRecord *Queue ;
int IsEmpty(Queue Q) ;
int IsFull(Queue Q) ;
Stack CreateQueue(int MaxElements) ;
void DisposeQueue Q(Queue Q) ;
void MakeEmpty(Queue Q) ;
void Enqueue(ElementType X,Queue Q) ;
ElementType Front(Queue Q) ;
void Dequeue(Queue Q) ;
ElementType FrontAndQueue(Queue Q) ;
#define MinQueueSize(5) ;
Struct QueueRecord
{
int capacity ;
int Front ;
int Rear ;
int Size ;
ElementType *Array ;
}
檢測隊列是否為空和構造空隊列
void IsEmpty(Queue Q)
{
return Q->Size == 0 ;
}
void MakeEmpty(Queue Q)
{
Q->Size = 0 ;
Q->Front = 1 ;
Q->Rear = 0 ;
}
Eequeue入隊函數
void Enqueue(ElementType X, Queue Q)
{
if(IsFull(Q)
Error("隊列已滿") ;
Q->Size++ ;
Q->Rear = Succ(Q->Rear,Q) ;
Q->Array[Q->Rear] = X ;
}
int Succ(int Value, Queue Q)
{
if(++Value == Q->Capacity)
Value = 0 ;
return Value ;
}
Dequeue出隊函數
ElementType Dequeue(Queue Q)
{
ElementType Tmp ;
if(Q->Rear < Q->Front)
Error("隊列為空") ;
Q->Size++ ;
Tmp = Q->Array[Q->Front] ;
Q->Front = Succ(Q->Front,Q) ;
return Tmp ;
}
總結
- 棧和隊列都屬於表的一種,只是支持更特殊的操作而已
- 且用途廣泛
