【定义】
栈是限定仅在表尾进行插入和删除操作的线性表,栈的插入就是压栈,栈的删除就是出栈,为后进先出结构,出栈的地方叫做栈顶。
【基本结构】
一共有两种栈的存储方式,一种顺序栈,通常由数组实现,另一种链栈,由单链表指针实现,顺序栈选择数组首元素作为栈顶,链栈选择头指针位置作为栈顶。
顺序栈基本结构:
typedef int stack_data;
typedef struct My_stack
{
stack_data data[MAXSIZE];//MAXSIZE宏定义
int top; //定义头指针
}my_stack;
这里需要注意头指针位置的问题,容易混淆,空栈,top = -1,满栈,top = 最后一个元素下标位置,一个元素进栈,top+1。
链栈基本结构:
typedef int Stack_data;
typedef struct StackNode
{
Stack_data data;
struct StackNode *next;
}my_stack, * my_stack_ptr;
typedef struct LinkStack
{
my_stack_ptr top;
int count;
}LinkStack;
这里需要注意,对于链栈,基本没有满栈一说,除非内存没了,头指针直接就是栈顶指针,栈顶指针就是第一个结点,所以无需头结点,空栈的意思就是top = NULL, 这里的top是指向链栈结点的指针,所以为空时就是空栈。
【进栈分析】
对于顺序栈来说,进栈的操作就是栈顶的移动,对于链栈来说,是栈顶指针永远指向新结点,在单链表操作中算是前部插入。
【出栈分析】
对于顺序栈,出栈,就是移动top下标,出一个,top-1,直至top = -1时说明空栈了;
对于链栈,出栈,同样移动top指针,出一个,top向后移一个,直至top = NULL说明空栈了。
【顺序栈测试代码】
#include<stdio.h>
#include<stdlib.h>
#define OK 0
#define ERROR 1
#define MAX 10
typedef int my_data;
typedef struct my_stack
{
my_data data[MAX];
int top;
}my_stack;
int push(my_stack *s, my_data e)
{
if(s->top == MAX-1)
return ERROR;
s->top++;
s->data[s->top] = e;
return OK;
}
int pop(my_stack *s, my_data *e)
{
if(s->top == -1)
return ERROR;
*e = s->data[s->top];
s->top --;
return OK;
}
void test(my_stack *s, my_data *e)
{
int d[] = {1,2,3,4,5,6,7,8};
int length = 8;
printf("进栈顺序:\n");
for(int i =0 ; i<length; i++)
{
printf("%d",d[i]);
push(s, d[i]);
}
printf("\n");
printf("出栈顺序:\n");
while(length--)
{
pop(s,e);
printf("%d",*e);
}
printf("\n");
}
void main()
{
my_stack *s= (my_stack *)malloc(sizeof(my_stack));
s->top = -1;
my_data *e = (my_data *)malloc(sizeof(my_data));
test(s,e);
}
【链栈测试代码】
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define MAX 10
typedef int my_data;
typedef int Stack_data;
typedef struct StackNode
{
Stack_data data;
struct StackNode *next;
}my_stack, * my_stack_ptr;
typedef struct LinkStack
{
my_stack_ptr top;//栈顶是一个指针
int count;
}LinkStack;
void init(LinkStack *s)
{
my_stack_ptr first = (my_stack_ptr)malloc(sizeof(my_stack));
first->next = NULL;
s->top = first;
s->count = 0;
}
int stack_empty( LinkStack s )
{
if(s.top->next==NULL)
return OK;
else
return ERROR;
}
int push(LinkStack *s, my_data e)
{
my_stack_ptr pnew = (my_stack_ptr )malloc(sizeof(my_stack ));
pnew ->data = e;
pnew-> next = s ->top;
s->top = pnew;
s->count++;
return OK;
}
int pop(LinkStack *s , my_data *e)
{
my_stack_ptr p;
if(stack_empty(*s))
return ERROR;
*e = s->top->data;
p = s->top;
s->top = s->top->next;
free(p);
s->count --;
return OK;
}
void test(LinkStack *s, my_data *e)
{
int d[] = {1,2,3,4,5,6,7,8};
int length = 8;
printf("进栈顺序:\n");
for(int i =0 ; i<length; i++)
{
printf("%d",d[i]);
push(s, d[i]);
}
printf("\n");
printf("出栈顺序:\n");
while(length--)
{
pop(s,e);
printf("%d",*e);
}
printf("\n");
}
void main()
{
LinkStack *s= (LinkStack *)malloc(sizeof(LinkStack));
s->count = -1;
my_data *e = (my_data *)malloc(sizeof(my_data));
test(s,e);
}
【栈测试输出】