一、栈的原理
栈 是限制在一端 进行插入操作 和删除操作 的线性表 (俗称堆栈 )
允许进行操作的一端称为“栈顶 ”
另一固定端称为“栈底 ”
当栈中没有元素时称为“空栈 ”。栈的特点 :后进先出(LIFO) 。
二、顺序栈的实现
有关顺序表的原理及实现看这篇文章: 【数据结构与算法】程序内功篇二–线性顺序表
1、顺序栈原理
它是顺序表 的一种,具有顺序表同样的存储结构,由数组 定义,配合用数组下标 表示的栈顶指针top(相对指针) 完成各种操作。
结构体定义:
typedef int data_t ;
typedef struct
{
data_t *data ;
int maxlen;
int top ;
} sqstack;
2、栈的创建
sqstack* stack_create(int len) {
sqstack * s;
if ((s =(sqstack *)malloc(sizeof(sqstack))) == NULL)
{
printf("malloc sqstack failed\n");
return NULL;
}
if ((s->data = (data_t *)malloc(len * sizeof(data_t)))==NULL)
{
printf("malloc data failed\n");
free(s);
return NULL;
}
memset(s->data, 0, len*sizeof(data_t));
s->maxlen = len;
s->top = -1;
return s;
}
3、顺序栈进栈
int stack_push(sqstack *s, data_t value)
{
if (s == NULL) {
printf("s is NULL\n");
return -1;
}
if (s->top == s->maxlen-1)
{
printf("stack is full\n");
return -1;
}
s->top++;
s->data[s->top] = value;
return 0;
}
4、顺序栈出栈
data_t stack_pop(sqstack *s) {
s->top--;
return (s->data[s->top+1]);
}
5、顺序栈删除
int stack_free(sqstack *s) {
if (s == NULL) {
printf("s is NULL\n");
return -1;
}
if (s->data != NULL)
free(s->data);
free(s);
return 0;
}
6、清空栈与是否清空栈
int stack_clear(sqstack *s) {
if (s == NULL) {
printf("s is NULL\n");
return -1;
}
s->top = -1;
return 0;
}
int stack_empty(sqstack *s)
{
if (s == NULL) {
printf("s is NULL\n");
return -1;
}
return (s->top == -1 ? 1 : 0);
}
三、链表栈的实现
有关链表的原理及实现请看这篇文章: 【数据结构与算法】程序内功篇三–单链表
1、栈的单链表实现
插入操作 和删除操作 均在链表头部 进行,链表尾部 就是栈底 ,栈顶指针 就是头指针 。
结点定义:
typedef int data_t ;
typedef struct node {
data_t data ;
struct node *next ;
}stacklist,*stacklink;
2、创建空栈
stacklink stacklist_create()
{
stacklink top;
if((top = (stacklink)malloc(sizeof(stacklist))) == NULL)
{
#if DEBUG
printf("stacklist create error!\n");
#endif
return 0;
}
top->data = 0;
top->next = NULL;
return top;
}
3、入栈
int stacklist_top_insert(stacklink top, data_t value)
{
stacklink sl;
if(top == NULL)
{
#if DEBUG
printf("top is NULL!\n");
#endif
return 0;
}
if((sl = (stacklink)malloc(sizeof(stacklist))) == NULL)
{
#if DEBUG
printf("stacklist create error!\n");
#endif
return 0;
}
sl->data = value;
sl->next = top->next;
top->next = sl;
return 1;
}
4、出栈
int stacklist_out(stacklink top)
{
stacklink sl;
int value;
if(top == NULL)
{
#if DEBUG
printf("top is NULL!\n");
#endif
return 0;
}
if(top->next == NULL)
{
#if DEBUG
printf("stacklist is empty!\n");
#endif
return 0;
}
sl = top->next;
top->next = sl->next;
value = sl->data;
free(sl);
return value;
}
5、删除链表栈
int stacklist_free(stacklink top)
{
stacklink sl = top;
if(top == NULL)
{
#if DEBUG
printf("top is NULL!\n");
#endif
return 0;
}
while(top)
{
top = top->next;
free(sl);
sl = top;
}
return 1;
}
6、判断是否为空栈
int stacklist_empty(stacklink top)
{
if(top == NULL)
{
#if DEBUG
printf("top is NULL!\n");
#endif
return -1;
}
return (top->next == NULL? 1:0);
}
四、栈的应用
建立操作数栈 和运算符栈 。运算符 有优先级。
①自左至右 扫描表达式,凡是遇到操作数 一律进操作数栈 。 ②当遇到运算符 时,如果它的优先级 比运算符栈栈顶元素的优先级高就进栈。反之,取出栈顶运算符 和操作数栈栈顶 的连续两个操作数 进行运算,并将结果 存入操作数栈 ,然后继续比较该运算符与栈顶运算符的优先级。 ③左括号 一律进运算符栈 ,右括号 一律不进运算符栈 ,取出运算符栈顶运算符 和操作数栈顶 的两个操作数 进行运算,并将结果压入操作数栈 ,直到取出左括号为止。
例如:计算 ( 4+8 )×2-3 ;
操作数栈 :4 8 | 12 2 |24 3 |21
运算符栈 :( + |× |- |
想要基本实现程序的点击下面的链接免费的: 栈的基本C程序
到这里就结束啦!
|