堆栈
定义:
1、只允许在一端插入和删除的线性表
2、允许插入和删除的一端称为栈顶,另一端称为栈底。
特点:
后进先出(LIFO)
堆栈进出栈图解
此处的top称为栈顶指针,但它不是真的指针,它只是指向数组的元素位置。
进栈操作是先将top++,再嵌入值
出栈操作是先取出当前top指向位置的值,之后将top--。
顺序栈的框架构建
#include<stdio.h>
#include<stdlib.h>
#define SIZE 10
enum ret_val{MALLOC_OK=100,MALLOC_NO,CREATE_OK,CREATE_NO,FULL_OK,FULL_NO,EMPTY_OK,EMPTY_NO,PUSH_OK,PUSH_NO,POP_OK,POP_NO};
struct stack_node
{
int stack_data[SIZE];
int top;
};
typedef struct stack_node Stack;
void create_stack(Stack ** stack)
{
*stack=(Stack *)malloc(sizeof(Stack));
if(MALLOC_OK==is_malloc_ok(Stack *stack))
{
return CREATE_OK;
}
return CREATE_NO;
}
void init_stack(Stack *stack)
{
stack->top=-1;
}
int is_full(Stack * stack)
{
if(stack->top>=SIZE-1)
{
return FULL_OK;
}
return FULL_NO;
}
int push_stack(Stack * stack,int num)
{
if(FULL_NO==is_full(stack)&&CREATE_OK==create_stack(Stack *stack))
{
//stack->top++;
stack->stack_data[++stack->top]=num;
printf("%d ",stack->stack_data[stack->top]);
return PUSH_OK;
}
printf("stack is full!\n");
return PUSH_NO;
}
int is_empty(Stack * stack)
{
if(stack->top<0)
{
return EMPTY_OK;
}
return EMPTY_NO;
}
int pop_stack(Stack * stack)
{
if(EMPTY_NO==is_empty(stack))
{
return stack->stack_data[stack->top--];
}
printf("stack is empty!\n");
return POP_NO;
}
int is_malloc_ok(Stack * stack)
{
if(NULL==stack)
{
return MALLOC_NO;
}
return MALLOC_OK;
}
int main()
{
Stack * stack=NULL;
int i;
int num=0;
create_stack(&stack);
init_stack(stack);
for(i=0;i<10;i++)
{
if(PUSH_OK==push_stack(stack,i+1))
{
printf("push stack success!\n");
}
else
{
printf("push stack fail!\n");
}
}
for(i=0;i<10;i++)
{
num=pop_stack(stack);
if(POP_NO!=num)//pop_stack(stack)
{
printf("%d ",num);//pop_stack(stack)
printf("pop stack success!\n");
}
else
{
printf("pop stack fail!\n");
}
}
free(stack);
return 0;
}
链式栈
此种栈不存在栈满问题,空间可扩充,插入与删除仅在栈顶处执行,该栈的栈顶在链头,适合多栈操作。
队列
定义:
队列是只允许在一端删除,在另一端插入的线性表允许删除的一端叫做队头,允许插入的一端叫做队尾。
特性:
先进先出(FIFO)
队列进队出队操作
- 进队时队尾指针先进一 rear = rear + 1,再将新元素按 rear 指示位置加入。
- 出队时队头指针先进一 front = front + 1,再将下标为 front 的元素取出。
- 队满时再进队将溢出出错; 队空时再出队将队空处理。
- 解决办法之一:将队列元素存放数组首尾相接,形成循环(环形)队列。
循环队列
队列存放数组被当作首尾相接的表处理。
队头、队尾指针加1时从QueueSize -1直接进到0,可用语言的取模(余数)运算实现。
- 队头指针进1: front = (front+1) % QueueSize;
- 队尾指针进1: rear = (rear+1) % QueueSize;
- 队列初始化:front = rear = 0;
- 队空条件:front == rear;
- 队满条件:(rear+1) % QueueSize == front