前面简单介绍一下栈和队列的概念,慢慢来.还是先写写栈吧.
由于前面学习了链表和线性表,所以栈的操作比较容易,先来指针栈吧.指针栈是以数组为基础的数据结构.入栈出栈都基于数组操作.
先看看栈的声明:
指针栈的声明:
#include <stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 100 //栈空间的初始分配量
#define STACKINCREMENT 10 //存储空间的分配增量
typedef int SElemType;
typedef struct
{
SElemType *base; //在构造栈之前和销毁栈之后,base的数值为NULL
SElemType *top; //栈顶指针
int stacksize; //显示栈当前的容量
}SqStack;
与栈有关的基本操作:
//创建一个空栈
int InitStack(SqStack *s);
//销毁栈
int DestroyStack(SqStack *s);
//清空栈
int ClearStack(SqStack *s);
//判断栈是否为空栈
int StackEmpty(SqStack *s);
//计算栈的长度
int StackLength(SqStack *s);
//获取栈顶元素
int GetTop(SqStack *s);
//将一个元素推入站内
int Push(SqStack *s,SElemType data);
//将一个元素退出栈
int Pop(SqStack *s);
//对于栈内的每一个元素调用函数
int StackTraverse(SqStack *s);
这些只是栈的基本操作但是这些操作是后面较复杂算法如层次遍历二叉树,广度优先搜索的基础操作.
下面是函数的具体代码:
int InitStack(SqStack *s)
{
s->base = (SElemType *)malloc(sizeof(SElemType)*STACK_INIT_SIZE); //为栈分配基础空间
if(!s->base)exit(1); //分配失败的话就退出
s->top = s->base; //栈顶指针指向栈底
s->stacksize = STACK_INIT_SIZE; //初始化栈的大小
return 1;
}
int Push(SqStack *s,SElemType data)
{
if(s->top-s->base >= s->stacksize) //如果栈的空间不够再增加
{
s->base = (SElemType *)realloc(s->base,(s->stacksize + STACKINCREMENT)*sizeof(SElemType));
if(!s->base)exit(1); //在原来空间的基础上额外增加空间
s->top = s->base + s->stacksize; //栈顶指针加1
s->stacksize += STACKINCREMENT; //栈大小增加
}
*s->top++ = data; //元素入栈,栈顶指针加1
return 1; //入栈成功
}
int Pop(SqStack *s)
{
if(s->base == s->top) return 0; //如果栈为空栈返回出栈失败
(*--s->top); //栈顶指针减1
return 1; //出栈成功
}
int GetTop(SqStack *s)
{
if(s->base == s->top)
return 0; //空栈返回失败
return *(s->top-1); //返回栈顶元素
}
int StackLength(SqStack *s)
{
SElemType *tmp = s->top; //设置临时变量和栈顶指针相同
int flag = 0;
while(tmp != s->base) //栈顶指针逐个减1知道栈底
{
flag ++;
tmp--;
}
return flag; //返回栈的长度
}
int DestroyStack(SqStack *s)
{
free(s->base); //释放掉栈的分配空间
s->base = s->top = NULL; //栈顶和栈底指向NULL
s->stacksize = 0; //栈的长度还原为0
return 1;
}
int ClearStack(SqStack *s)
{
s->top = s->base; //栈清空最方便只需要将栈顶指针指向栈底
return 1;
}
int StackTraverse(SqStack *s)
{
SElemType *tmp = (s->top-1);
if(s->top == s->base)return 0;
while(1)
{
printf("%d ",*tmp);
if(tmp == s->base) break; //这个地方我刚刚犯了一个错误就是忽视栈底base指针指向的区域也有一个数据
tmp--;
}
return 1;
}