數據結構筆記(三)棧與隊列
棧(stack)和隊列(queue)是兩種重要的線性結構
口從數據結構角度看,棧和隊列也是線性表,其特殊性在於它們的基本操作是線性表的子集,是操作受限的線性表,可稱爲限定性的數據結構從數據類型角度看,其操作規則與線性表大不相同,是完全不同於線性表的抽象數據類型。
- 棧按“後進先出”的規則進行操作
- 隊列按“先進先出”的規則進行操作棧和隊列是操作受限的特殊線性表
1.棧
棧:限定在表尾進行插入和刪除操作的線性表
■棧頂(表尾):棧中允許插入、刪除的一端
■棧底(表頭):棧中不允許插入、刪除的一端插入也稱爲進棧(壓棧);刪除也稱爲出棧(退棧)
我們主要討論的是順序棧
儲存結構的定義:
#define stack_init_size 100; //儲存空間初始分配量
#define stackincrement 10; //儲存空間分配增量
typedef struct
{
SElemType *base; //棧基址
SElemType *top; //棧頂指針
int stacksize; //堆棧的大小
}SqStack;
初始化棧:
status Initstack(Sqstack &s)
{
s.base=(SElemType *)malloc(stack_init_size *sizeof(SElemType));
if(!s.base) exit(OVERFLOW);
s.top=s.base;
s.stacksize=stack_init_size;
return OK;
}
入棧:
status Push(Sqstack &s,Selemtype e) //插入e爲新的棧頂元素
{
if(s.top-s.base>=s.stacksize) //棧滿,追加儲存空間
{
s.base=(SElemType *)realloc(s.base,(s.stacksize+Stackincrement)*sizeof(SElemType));
if(!s.base) exit(OVERFLOW); //分配失敗
s.top=s.base+s.stacksize;
s.stacksize+=stackincrement;
}
*s.top++=e; //入棧
return OK;
}
出棧:
Status Pop(SqStack &s,SElemType &e)
{
if(s.top==s.base) //是否棧空?
return ERROR;
e=*--s.top;
return OK;
}
2.隊列
1.隊列的基本定義
隊列(Queue)是一種運算受限的線性表。它只允許在表的一端進行插入,而在另一端進行刪除。允許刪除的一端稱爲隊頭(front),刪除也稱出隊列允許插入的一端稱爲隊尾(rear),插入也稱入隊列口特點:先進先出
2.儲存結構類型定義
typedef struct QNode
{
QElemType data; //隊列元素類型
struct QNode *next; //指向下一隊列元素指針
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front; //隊列頭指針
QueuePtr rear; //隊列尾指針
}LinkQueue;
3.初始化
status Initqueue(linkqueue &Q)
{
Q.front=Q.rear=(QueuePtr)malloc(sizeof(Qnode));
if(!Q.front) exit(OVERFLOW); //頭結點爲0則退出
Q.front->next=NULL;
return OK;
}
4.銷燬隊列
status Destroyqueue(linkqueue &Q)
{
while(Q.front)
{
Q.rear=Q.front->next; //從隊列頭開始刪除
free(Q.front);
Q.front=Q.rear;
}
return OK;
}
5.插入
status Enqueue(linkqueue &Q,Qelemtype e)
{
p=(QueuePtr)malloc(sizeof(QNode));
if(!p) exit(OVERFLOW)
p->data=e; //先定義好結點
p->next=NULL;
Q.rear->next=p; //然後再連接
Q.rear=p; //尾指針移動
return OK;
}
//元素入隊時,只需修改尾指針
6.刪除
status Dequeue(linkqueue &Q,Qelemtype &e)
{
if(Q.front==Q.rear) return ERROR; //隊空
p=Q.front->next;
e=p->data;//得到出列數據
Q.front->next=p->next; //跨越連接
if(Q.rear==p) Q.rear=Q.front; //刪除的是最後一個結點
free(p);
return OK;
}
//刪除隊列頭元素時,一般僅修改頭結點的指針即可
//但當隊列中最後一個元素被刪除後,隊尾指針丟失,因此需對隊列尾指針重新賦值