由于栈本身就是线性表,于是栈也有顺序存储和链式存储两种实现方式
使用数组作为顺序栈存储方式的特点:
简单方便、但易产生溢出(数组大小固定)
上溢(overflow): 栈已经满,又要压入元素
下溢(underflow): 栈已经空,还要弹出元素
顺序栈的表示
#define MAXSIZE 100
typedef struct{
SElemType *base; //栈底指针
SElemType *top; //栈顶指针
int stacksize; //栈可用最大容量
}SqStack;
Status InitStack(SqStack &S){//构造一个空栈
S.base = new SElemType[MAXSIZE];
//或S.base = (SElemType*)malloc(MAXSIZE*sizeof(SElemType));
if (!S.base) exit (OVERFLOW); //存储分配失败
S.top= S.base; //栈顶指针等于栈底指针
S.stacksize = MAXSIZE;
return OK;
}
Status StackEmpty(SqStack S)
// 若栈为空,返回TRUE;否则返回FALSE
if (S.top == S.base)
return TRUE;
else
return FALSE;
}
int StackLength( SqStack S)
{
return S.top - S.base;
}
Status ClearStack( SqStack S ) {
if( S.base ) S.top = S.base;
return OK;
}
Status DestroyStack( SqStack &S ){
if(S.base ) {
delete S.base ;
S.stacksize = O;
S.base = S.top = NULL;
}
return OK;
}
Status Push( SqStack &S, SElemType e) {
if( S.top - S.base== S.stacksize )//栈满
return ERROR;
*S.top++=e; //*S.top=e; S.top++;
return OK;
}
Status Pop(SqStack &S, SElemType &e){
//若栈不空,则删除S的栈顶无素,用e返回其值,并返回OK;否则返回ERROR
if(S.top == S.base) //等价于if(StackEmpty(S))
return ERROR;
e = *--S.top; //--S.top; e=*S.top;
retum OK;
}
typedef struct StackNode{
SElemType data;
struct StackNode *next;
} StackNode,*LinkStack;LinkStack S;
void lnitStack(LinkStack &S ) {//构造一个空栈,栈顶指针置为空
S=NULL;
return OK;
}
Status StackEmpty(LinkStack S)
if (S==NULL) return TRUE;
else return FALSE;
}
Status Pop (LinkStack &S,SElemType &e){
if (S==NULL) return ERROR;
e = S-> data;
p = S;
S = S-> next;
delete p;
return OK;
}
SElemType GetTop(LinkStack S) {
if (S!=NULL)
return S->data;
}
若一个对象部分地包含它自己 ,或用它自己给自己定义,则称这个对象是递归的;
若一个过程直接地或间接地调用自己,则称这个过程是递归的过程。
例如:涕归求n的阶乘
long Fact ( long n ) {
if ( n == 0) return 1;
else return n * Fact (n-1);
}
以下三种情况常常用到递归方法
队列的物理存储可以用顺序存储结构,也可用链式存储结构, 队列的存储方式也分为两种,即顺序队列和链式队列。
队列的顺序表示——用一维数组base[MAXQSZE]
#define MAXQSIZE 100//最大队列长度
Typedef struct {
QElemType *base;//初始化的动态分配存储空间
int front; //头指针
int rear //尾指针
}SqQueue;
#define MAXQSIZE 100//最大队列长度
typedef struct {
QElemType *base;//动态分配存储空间
int front; //头指针,若队列不空,指向队列头元素
int rear; //尾指针,若队列不空,指向队列尾元素的下一个位置
} SqQueue;
Status lnitQueue (SqQueue &Q){
Q.base =new QElemType[MAXQSIZE] //分配数组空间
//Qbase = (QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
if(!Q.base)exit(OVERFLOW); //存储分配失败
Q.front=Q.rear=O; //头指针尾指针置为0,队列为空
return OK;
}
int QueueLength (SqQueue Q){
return (Q.rear-Q.front+MAXQSIZE)% MAXQSIZE );
}
Status EnQueue(SqQueue &Q, QElemTypee){
if((Q.rear+1)%MAXQSIZE==Q.front) return ERROR; //队满
Q.base[Q.rear]=e; //新元素加入队尾
Q.rear=(Qrear+1)%MAXQSIZE; //队尾指针+1
return OK;
}
Status DeQueue (SqQueue &Q,QElemType &e){
if(Q.front==Qrear) return ERROR; //队空
Q.base[Q.front]; //保存队头元素
Q.front=(Q.front+1)%MAXQSIZE; //队头指针+1
return OK;
}
SElemType GetHead(SqQuere Q){
if(Q.front!=Q.rear) //队列不为空
return Q.base[Q.front]; //返回队头指针元素的值,队头指针不变
}
#define MAXQSIZE 100 //最大队列长度
typedef struct Qnode {
QElemType data;
struct Qnode *next;
}QNode,*QuenePtr;
typedef struct {
QuenePtr front;//队头指针
QuenePtr rear;//队尾指针
}LinkQueue;
Status InitQueue (LinkQueue &Q){
Q.front=Q.rear=(QueuePtr) malloc(sizeof(QNode));
if(!Q.front) exit(OVERFLOW);
Q.front->next=NULL;
return OK;
}
Status DestroyQueue (LinkQueue &Q){
while(Q.front){
p=Q.front->next; //Q.rear=Q.front->next;
free(Q.front); //free(Q.front);
Q.front=p; //Q.front=Q.rear;
}
return OK;
}
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;
}
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;
delete p;
return OK;
}
Status GetHead (LinkQueue Q, QElemType &e){
if(Q.front==Q.rear) return ERROR;
e=Q.front->next->data;
return OK;
}
ueue &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;
}
### 【算法3.7】出队
[外链图片转存中...(img-QNfcYgtG-1641895287115)]
```c
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;
delete p;
return OK;
}
Status GetHead (LinkQueue Q, QElemType &e){
if(Q.front==Q.rear) return ERROR;
e=Q.front->next->data;
return OK;
}