目录
栈和队列不是传统意义上的线性表,它们属于特殊的线性表
栈
逻辑结构
定义:栈是只有一端能够插入删除的线性表。
特点:后进先出(LIFO)
基本操作
初始化操作InitStack(&S):创建一个新栈S。
销毁操作DestroyStack(&S):销毁一个栈S。
进栈操作Push(&S,x):若栈未满,压栈。
出栈操作Pop(&S,&x):若栈不为空,弹栈。
读栈顶元素Get(S,&x):若栈不为空,读栈顶元素并用x带回。
判空操作Empty(S):判断栈S是否为空栈。
物理结构
顺序结构
栈的定义
#define MaxSize 10
typedef struct
{
ElemType data[MaxSize];//栈空间
int top;//栈顶位置
}Stack;
初始化操作InitStack(&S)
void InitStack(Stack &S)
{
S.top=-1; //栈顶元素加一才指向此次插入的元素
}
void InitStack(Stack &S)
{
S.top=0; //栈顶元素指向此次插入的元素
}
销毁操作DestroyStack(&S)
void DestroyStack(Stack &S)
{
S.top=-1;
}
void DestroyStack(Stack &S)
{
S.top=0;
}
判空操作Empty(S)
bool Empty(Stack S)
{
if(S.top==-1)
return true;
return false;
}
bool Empty(Stack S)
{
if(S.top==0)
return true;
return false;
}
进栈操作Push(&S,x)
bool Push(Stack &S,ElemType x)
{
if(S.top==MaxSize-1)//栈满了
return false;
S.data[++S.top]=x;//先加一才能指到元素插入的位置
return true;
}
bool Push(Stack &S,ElemType x)
{
if(S.top==MaxSize)//栈满了
return false;
S.data[S.top++]=x;//栈顶指针指在插入元素位置,插入完元素加一
return true;
}
出栈操作Pop(&S,&x)
bool Pop(Stack &S,ElemType &x)
{
if(S.top==-1)//栈空
return false;
x=S.data[S.top--];//先把栈顶元素赋值给x再把栈顶指针减一删掉这个元素
return true;
}
bool Pop(Stack &S,ElemType &x)
{
if(S.top==0)//栈空
return false;
x=S.data[--S.top];//栈顶元素在栈顶的下一个,栈顶先减一指向其
return true;
}
读栈顶元素Get(S,&x)
bool Get(Stack S,ElemType &x)
{
if(S.top==-1)
return false;
x=S.data[S.top];
return true;
}
bool Get(Stack S,ElemType &x)
{
if(S.top==0)
return false;
ElemType y=S.top-1;
x=S.data[y];
return true;
}
链式存储
栈的定义
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode,*Stack;
初始化操作InitStack(&S)
void InitStack(Stack &S)//不带头结点
{
S=NULL;
}
判空操作Empty(S)
bool Empty(Stack S)
{
if(S==NULL)//空栈
return true;
return false;
}
进栈操作Push(&S,x)
bool Push(Stack &S,ElemType x)
{
LNode *p=(LNode *)malloc(sizeof(LNode));
if(p==NULL)
{
return false;
}
p->data=x;
p->next=S;
S=p;
return true;
}
出栈操作Pop(&S,&x)
bool Pop(Stack &S,ElemType &x)
{
if(S==NULL)//空栈
{
return false;
}
x=S->data;
LNode *p=S;
S=S->next;
free(p);
return true;
}
读栈顶元素Get(S,&x)
bool Get(Stack S,ElemType &x)
{
if(S==NULL)//空栈
{
return false;
}
x=S->data;
return true;
}
队列
逻辑结构
定义:队列是只有一端能够插入,只有另一端能删除的线性表。
但其实在实际应用时逻辑结构应该采用循环队列,代码对物理结构的操作也是基于此种逻辑结构。
特点:先进先出(FIFO)
基本操作
初始化操作InitQueue(&q):创建一个新队列q。
销毁操作DestroyQueue(&q):销毁一个队列q。
入队操作InQueue(&q,x):若队未满,入队。
出队操作OutQueue(&q,&x):若队不为空,出队。
读队头元素Get(q,&x):若队列不为空,读队头元素并用x带回。
判空操作Empty(q):判队列是否为空。
判满操作IsFull(q):判断队列q是否为满。
队列长度Length(q):得到队列的长度。
物理结构
顺序结构
定义
#define MaxSize 10
typedef struct
{
ElemType data[MaxSize];
int front;//队头指针
int rear;//队尾指针
}Queue;
InitQueue(&q)
void InitQueue(Queue &q)
{
q.front=q.rear=0;
}
DestroyQueue(&q)
void DestroyQueue(Queue &q)
{
q.front=q.rear=0;
}
InQueue(&q,x)
bool InQueue(Queue &q,ElemType x)
{
if(IsFull(q)==true)
return false;
q.data[q.rear]=x;
q.rear=(q.rear+1)%MaxSize;
return true;
}
OutQueue(&q,&x)
bool OutQueue(Queue &q,ElemType &x)
{
if(Empty(q)==true)//空队
{
return false;
}
x=q.data[q.front];
q.front=(q.front+1)%MaxSize;
return true;
}
Get(q,&x)
bool Get(Queue q,ElemType &x)
{
if(Empty(q)==true)//空队
{
return false;
}
x=q.data[q.front];
return true;
}
Empty(q)//浪费一个空间的情况
bool Empty(Queue q)
{
if(q.front==q.rear)//
return true;
return false;
}
IsFull(q)//浪费一个空间的情况
bool IsFull(Queue q)//这里用浪费一个空间的办法
{
if((q.rear+1)%MaxSize==q.front)
return true;
return false;
}
Length(q)
int Length(Queue q)
{
if(Empty(q)==true)
{
return 0;
}
if(IsFull(q)==true)
return MaxSize-1;//因为浪费一个空间
return (q.rear+MaxSize-q.front)%MaxSize;
}
不浪费空间判断队满队空的情况
(1)在队列结构体在定义一个size变量记录队元素个数。
(2)用flag变量记录上一步的操作是入队还是出队,入队1,出队0,如果头尾指针相同,上一步操作是1即队满,上一步为0即队空。
链式存储
定义
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode;
typedef struct
{
LNode *front,*rear;
}Queue;
InitQueue(&q)
bool InitQueue(Queue &q)//带头结点
{
LNode *s=(LNode *)malloc(sizeof(LNode));
if(s==NULL)
{
return false;
}
q.front=s;
q.rear=s;
s->next=NULL;
return true;
}
bool InitQueue(Queue &q)//不带头结点
{
q.front=NULL;
q.rear=NULL;
return true;
}
InQueue(&q,x)
bool InQueue(Queue &q,ElemType x)//带头结点
{
LNode *s=(LNode *)malloc(sizeof(LNode));
if(s==NULL)
return false;
s->data=x;
s->next=NULL;
q.rear->next=s;
q=s;
return true;
}
bool InQueue(Queue &q,ElemType x)//不带头结点
{
LNode *s=(LNode *)malloc(sizeof(LNode));
if(s==NULL)
return false;
s->data=x;
if(Empty(q))
{
q.front=s;
q.rear=s;
return true;
}
s->next=NULL;
q.rear->next=s;
q=s;
return true;
}
OutQueue(&q,&x)
bool OutQueue(Queue &q,ElemType &x)//带头结点
{
if(Empty(q)==true)//空队
{
return false;
}
x=q.front->next->data;
LNode *p=q.front->next;
q.front->next=p->next;
if(q.rear==p)
{
q.rear=q.front;
}
free(p);
return true;
}
Get(q,&x)
bool Get(Queue q,ElemType &x)//带头结点
{
if(Empty(q)==true)//空队
{
return false;
}
x=q.front->next->data;
return true;
}
bool Get(Queue q,ElemType &x)//不带头结点
{
if(Empty(q)==true)//空队
{
return false;
}
x=q.front->data;
return true;
}
Empty(q)
bool Empty(Queue q)//带头结点
{
if(q.front->next=NULL)//
return true;
return false;
}
bool Empty(Queue q)//不带头结点
{
if(q.front=NULL)//
return true;
return false;
}