栈的概念
栈(stack):是限制在表的一端进行插入和删除操作的线性表。又称为后进先出LIFO(Last In First Out)或先进后出FILO(First In Last Out)线性表。
栈顶(Top):允许进行插入、删除操作的一端,又称表位。
栈底:(Bottom):是固定端,又称表头。
空栈:当表中没有元素时称为空栈。
栈的顺序存储表示
存储栈分为静态存储栈和动态存储栈。
静态顺序栈实现简单,但不能根据需要增大栈的空间;
动态顺序栈可以根据需要增大栈的存储空间,但实现起来稍微复杂。
栈的静态顺序存储表示
采用静态一维数组来存储栈。
栈底固定不变,而栈顶随着进栈和退栈操作变化。
栈的类型定义
typedef struct sqstack {
ElemType stack_array[MAX_STACK_SIZE];
int top;
}SqStack;
栈的初始化
void Init_Stack(SqStack* S) {
/* 构造一个空栈 */
S->top = -1;
}
压栈(元素进栈)
Status push(SqStack* S, ElemType e) {
/* 使数据元素e进栈成为新的栈顶 */
if (S->top == MAX_STACK_SIZE - 1)
return ERROR; /* 栈满,返回错误标志 */
S->top++; /*栈顶指针+1*/
S->stack_array[S->top] = e; /* e成为新的栈顶 */
return OK; /*压栈成功*/
}
弹栈(元素出栈)
int Pop(SqStack* S, int* x) {
/* 将栈S的栈顶元素弹出,放到x所指的存储空间中 */
if (S->top == -1) /* 栈为空 */
return ERROR;
else {
*x = S->stack_array[S->top];
S->top--; /* 修改栈顶指针 */
return(*x);
}
}
获取栈顶元素
int GetTop(SqStack* S, int* x) {
/* 将栈S的栈顶元素弹出,放到x所指的存储空间中 */
if (S->top == -1) /* 栈为空 */
return ERROR;
else {
*x = S->stack_array[S->top];
return(*x);
}
}
获取栈中结点数量
int StackSize(SqStack S) {
int stack_num=1; /* 栈顶记为 1 */
while (S.top != -1) {
S.top--;
stack_num++;
}
}
打印栈中数据元素
void Printf_Stack(SqStack S) {
printf("输出的栈为:\n");
while (S.top != -1) {
printf(" %d %d\n", S.top, S.stack_array[S.top]);
S.top--;
}
printf("%d", S.top);
}
数值转换----由十进制转换为二进制、八进制
/* 数值转换
* 采用静态顺序栈方式实现
*/
void Conversion(int n, int d) {
/* 将十进制整数N转换为d(2或8)进制数 */
SqStack S; int k, e;
Init_Stack(&S);
while (n > 0) {
/* 求出所有余数,进栈 */
k = n % d;
push(&S, k);
n = n / d;
}
while (S.top != -1) {
/* 栈不为空时,输出 */
Pop(&S, &e);
printf("%d", e);
}
}
main函数
Stack_Node stack;
int elem;
Init_Link_Stack(&stack);
Push_Link_Stack(stack, 3);
Pop_Link_Stack(&stack, &elem);
栈的静态顺序存储全部代码
#define _CRT_SECURE_NO_WARNINGS
#include "stack.h"
#include <stdlib.h>
#include<stdio.h>
typedef struct sqstack {
ElemType stack_array[MAX_STACK_SIZE];
int top;
}SqStack;
#define ERROR 0
#define OK 1
#define MAX_STACK_SIZE 100 /* 栈向量大小 */
typedef int ElemType;
typedef int Status;
void Init_Stack(SqStack* S) {
/* 构造一个空栈 */
S->top = -1;
}
Status push(SqStack* S, ElemType e) {
/* 使数据元素e进栈成为新的栈顶 */
if (S->top == MAX_STACK_SIZE - 1)
return ERROR; /* 栈满,返回错误标志 */
S->top++; /*栈顶指针+1*/
S->stack_array[S->top] = e; /* e成为新的栈顶 */
return OK; /*压栈成功*/
}
void Printf_Stack(SqStack S) {
printf("输出的栈为:\n");
while (S.top != -1) {
printf(" %d %d\n", S.top, S.stack_array[S.top]);
S.top--;
}
printf("%d", S.top);
}
int Pop(SqStack* S, int* x) {
/* 将栈S的栈顶元素弹出,放到x所指的存储空间中 */
if (S->top == -1) /* 栈为空 */
return ERROR;
else {
*x = S->stack_array[S->top];
S->top--; /* 修改栈顶指针 */
return(*x);
}
}
int GetTop(SqStack* S, int* x) {
/* 将栈S的栈顶元素弹出,放到x所指的存储空间中 */
if (S->top == -1) /* 栈为空 */
return ERROR;
else {
*x = S->stack_array[S->top];
return(*x);
}
}
/* 数值转换
* 采用静态顺序栈方式实现
*/
void Conversion(int n, int d) {
/* 将十进制整数N转换为d(2或8)进制数 */
SqStack S; int k, e;
Init_Stack(&S);
while (n > 0) {
/* 求出所有余数,进栈 */
k = n % d;
push(&S, k);
n = n / d;
}
while (S.top != -1) {
/* 栈不为空时,输出 */
Pop(&S, &e);
printf("%d", e);
}
}
int StackSize(SqStack S) {
int stack_num=1; /* 栈顶记为 1 */
while (S.top != -1) {
S.top--;
stack_num++;
}
}
int main(void) {
int n = 1348;
int d = 8;
Conversion(n, d);
}
栈的链式表示
栈的链式存储结构称为链栈,是运算受限的单链表。其插入和删除操作只能在表头位置上进行。因此链栈没有必要像单链表那样附加头结点。
栈的类型定义
typedef struct Stack_Node {
ElemType data; /* 数据域 */
struct Stack_Node* next; /* 指针域 */
}Stack_Node;
栈的初始化
void Init_Link_Stack(Stack_Node* top) {
top = (Stack_Node*)malloc(sizeof(Stack_Node));
top->next = NULL;
}
入栈(元素进栈)
Status Push_Link_Stack(Stack_Node* top, ElemType e) {
Stack_Node* p;
p = (Stack_Node*)malloc(sizeof(Stack_Node));
if (!p) return ERROR;
/*申请新结点失败,返回错误标志 */
p->data = e;
p->next = top->next;
top->next = p; /* 钩链 */
return OK;
}
弹栈(元素出栈)
Status Pop_Link_Stack(Stack_Node* top, int* x) {
Stack_Node* p;
if (top->next == NULL)
return ERROR; /* 栈空,返回错误标志 */
p = top->next;
(*x) = p->data; /* 取栈顶元素 */
top->next = p->next; /* 修改栈顶指针 */
free(top);
return OK;
}
链栈全部代码
#define _CRT_SECURE_NO_WARNINGS
#include "link_stack.h"
#include <stdlib.h>
#include<stdio.h>
#define ERROR 0
#define OK 1
typedef int ElemType;
typedef int Status;
typedef struct Stack_Node {
ElemType data; /* 数据域 */
struct Stack_Node* next; /* 指针域 */
}Stack_Node;
void Init_Link_Stack(Stack_Node* top) {
top = (Stack_Node*)malloc(sizeof(Stack_Node));
top->next = NULL;
}
Status Push_Link_Stack(Stack_Node* top, ElemType e) {
Stack_Node* p;
p = (Stack_Node*)malloc(sizeof(Stack_Node));
if (!p) return ERROR;
/*申请新结点失败,返回错误标志 */
p->data = e;
p->next = top->next;
top->next = p; /* 钩链 */
return OK;
}
Status Pop_Link_Stack(Stack_Node* top, int* x) {
Stack_Node* p;
if (top->next == NULL)
return ERROR; /* 栈空,返回错误标志 */
p = top->next;
(*x) = p->data; /* 取栈顶元素 */
top->next = p->next; /* 修改栈顶指针 */
free(top);
return OK;
}
int main(void) {
Stack_Node stack;
int elem;
Init_Link_Stack(&stack);
Push_Link_Stack(stack, 3);
Pop_Link_Stack(&stack, &elem);
}