目录
02 栈和队列
一、顺序栈
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*相关参数*/
#define MAXSIZE 1024
#define ElemType char
#define Status int
#define OK 1
#define ERR 0
/*定义结构体*/
typedef struct
{
ElemType *base; //栈底指针
ElemType *top; //栈顶指针
int stacksize; //栈可用最大容量
}SqStack;
/*函数声明*/
//初始化栈
Status InitStack(SqStack *S)
{// Initial创造一个空栈
S->base=(ElemType*) malloc(sizeof(ElemType)*MAXSIZE);//为顺序栈分配一个最大容量为MAXSIZE的数组空间
if(!S->base)return ERR;//如果分配存储失败
S->top=S->base;//top初始化为base
S->stacksize=MAXSIZE;//stacksize置为栈的最大容量MAXSIZE
return OK;
}
//入栈
Status Push(SqStack *S,ElemType e)
{
if(S->top-S->base ==S->stacksize)return ERR;//栈满
*(S->top)=e;//元素插入栈顶
S->top++;//栈顶上移
return OK;
}
//出栈
Status Pop(SqStack *S,ElemType *e)
{//删除栈顶元素,用e返回其值
if(S->top==S->base)return ERR;//栈空
*e=*(S->top-1);//元素取出栈顶
S->top--;//栈顶下移
return OK;
}
//取栈顶元素
ElemType GetTop(SqStack *S)
{
if(S->top!=S->base)
return *(S->top-1);
}
SqStack zhan;
int main()
{
char buffer;
InitStack(&zhan);
printf("入栈\n");
for(int i=65; i<90;i++)
{
char ch;
ch=i;
printf("%c ",ch);
Push(&zhan,ch);
}
printf("\n");
printf("出栈\n");
while (Pop(&zhan,&buffer))
{
printf("%c ",buffer);
}
return 0;
}
效果
可以看出顺序栈具有先入后出的特点。
二、链栈
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*相关参数*/
#define ElemType char
#define Status int
#define OK 1
#define ERR 0
/*链栈的存储结构*/
typedef struct StackNode
{
ElemType data;
struct StackNode *next;
}StackNode,*LinkStack;
/*函数声明*/
//链栈初始化
Status InitStack(LinkStack *S)
{
*S=NULL;
return OK;
}
//入栈
/*算法步骤
1.为入栈元素e分配空间,用指针p指向
2.将新节点数据域置为e
3.将新节点插入栈顶
4.修改栈顶指针为p
*/
Status Push(LinkStack *S,ElemType e)
{
StackNode*p;
p=(StackNode*) malloc(sizeof(StackNode));
p->data=e;
p->next=*S;
*S=p;
return OK;
}
//出栈
/*算法步骤
1.判断栈是否为空
2.临时保存栈顶指针,已备释放
3.将栈顶元素赋值给e
4.修改栈顶指针,指向新栈顶元素
5.释放原栈顶元素空间
*/
Status Pop(LinkStack *S,ElemType *e)
{
if((*S)==NULL)return ERR;
StackNode*p;
p=(*S);
*e=(*S)->data;
(*S)=(*S)->next;
free(p);
return OK;
}
//取栈顶元素
ElemType GetTop(LinkStack *S)
{
if(*S==NULL)return ERR;
return (*S)->data;//返回栈顶指针元素的值
}
int main()
{
char buffer;
LinkStack S;
printf("\n");
InitStack(&S);
printf("入栈\n");
for(int i=65; i<=90;i++)
{
char ch;
ch=i;
printf("%c ",ch);
Push(&S,ch);
}
printf("\n");
printf("出栈\n");
while (Pop(&S,&buffer))
{
printf("%c ",buffer);
}
return 0;
}
效果
三、栈与递归
递归就是函数自己调用自己
#include <stdio.h>
//递归就是函数自己调用自己
//例:
long Fact(long n)//阶乘函数
{
if(n==0)return 1;
else
{
return n*Fact(n-1);
}
}
#define FACT 1
#if FACT
int main()
{
printf("5的阶乘=%d",Fact(5));
}
#endif
四、队列
基本形式:
typedef struct {
QElemTye *base;//初始化的动态分配存储空间
int front;//头指针->写入
int rear;//尾指针->读出
}SqQueue;
1、利用数组表示环形队列
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERR 0
//顺序队列和链式队列
/*用一维数组表示队列*/
#define MAXQSIZE 100
typedef int QElemTye;
typedef int Status;
typedef struct {
QElemTye *base;//初始化的动态分配存储空间
int front;//头指针->写入
int rear;//尾指针->读出
}SqQueue;
//队空:front==rear
//对空:(rear+1)%MAXQSIZE==front
/*队列初始化*/
Status InitQueue(SqQueue *Q)
{
Q->base=malloc(MAXQSIZE*sizeof(QElemTye)); //分配数组空间
if(!(*Q->base))return ERR;
Q->front=Q->rear=0;
return OK;
}
/*求队列长度*/
int QueueLength(SqQueue Q)
{
return ((Q.rear-Q.front+MAXQSIZE)%MAXQSIZE);
}
/*循环队列入队*/
Status EnQueue(SqQueue *Q,QElemTye e)
{
if((Q->rear+1)%MAXQSIZE==Q->front)return ERR;//队满
(*Q).base[Q->rear]=e;//插入元素e
(*Q).rear=(Q->rear+1)%MAXQSIZE;//队尾指针+1,超出队顶则回到0位置
return OK;
}
/*循环队列出队*/
Status DeQueue(SqQueue *Q,QElemTye *e)
{
if(Q->rear==Q->front)return ERR;//队空
*e=(*Q).base[Q->front];
(*Q).front=(Q->front+1)%MAXQSIZE;//队头指针+1,超出队顶则回到0位置
}
/*循环队列取头元素*/
QElemTye GetHead(SqQueue Q)
{
if(Q.front!=Q.rear) //队列不为空
return Q.base[Q.front];
}
int main()
{
SqQueue queue;
InitQueue(&queue);
EnQueue(&queue,'x');
EnQueue(&queue,'h');
EnQueue(&queue,'z');
QElemTye c='\0';
printf("依次读出:\n");
for(int i=0; i<3;i++)
{
DeQueue(&queue,&c);
printf("%c\n",c);
}
}