栈和队列的基本操作是线性表操作的子集,它们是操作受限的线性表,因此,可称为限定性的数据结构。
栈(stack)
1.定义:限定只能在表的一端进行插入和删除操作运算的线性表(只能在栈顶操作)
2.逻辑结构:同线性表一样栈元素具有线性关系即前驱后继关系(一对一)
3.存储结构:顺序栈和链栈均可,顺序栈更常见
4.运算规则:只能在栈顶运算,且访问结点时依照后进后出的原则(LIFO)
5.实现方式:关键是编写入栈和出栈函数具体实现依顺序栈和链栈的不同而不同
栈和线性表唯一的区别在于运算规则。线性表插入删除位置任意而栈只能对表尾(栈顶)的元素进行插入和删除操作。(后进先出的原则)
-
表尾an端为栈顶Top
-
表头a1端栈底Base(Bottom)
-
不含元素的空表称为空栈。
-
插入元素到栈顶(表尾)的操作叫入栈(压栈)PUSH
-
从栈顶(表尾)删除最后一个元素的操作称为出栈(弹栈)POP
栈的基本操作
- 栈SS的初始化操作。
void InitStack(SS); - 销毁栈SS。
void DestroyStack(SS); - 清空栈。
void Clear(SS); - 元素入栈,返回值:0-失败;1-成功。
int Push(SS,ee); - 元素出栈,返回值:0-失败;1-成功。
int Pop(SS,ee); - 判断栈是否为空,返回值:1-空,0-非空或失败。
int IsEmpty(SS); - 判断栈是已满,返回值:1-已满,0-未满或失败。
int IsFull(SS); - 求栈的长度,返回栈SS元素的个数。
int Length(SS); - 获取栈顶元素,返回值:0-失败;1-成功。
int GetTop ( SS , ee ) ;
顺序栈
//SeqStac.h顺序栈
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using std::cin;
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define MAXSIZE 20
//Status 是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE]; // 用数组存储顺序栈中的元素。
int top; // 栈顶指针,从0到MAXSIZE-1,-1表示空栈。
// 也可以从1到MAXSIZE,0表示空栈。
}SeqStack, *PSeqStack;
// 顺序栈SS的初始化操作。
Status InitStack(PSeqStack SS);
// 销毁顺序栈SS。
void DestroyStack(PSeqStack SS);
// 元素入栈,返回值:0-失败;1-成功。
int Push(PSeqStack SS, ElemType *ee);
// 元素出栈,返回值:0-失败;1-成功。
int Pop(PSeqStack SS, ElemType *ee);
// 求顺序栈的长度,返回值:栈SS中元素的个数。
int Length(PSeqStack SS);
// 清空顺序栈。
void Clear(PSeqStack SS);
// 判断顺序栈是否为空,返回值:1-空,0-非空或失败。
int IsEmpty(PSeqStack SS);
// 判断顺序栈是否已满,返回值:1-已满,0-未满或失败。
int IsFull(PSeqStack SS);
// 打印顺序栈中全部的元素。
void PrintStack(PSeqStack SS);
// 获取栈顶元素,返回值:0-失败;1-成功。
// 只查看栈顶元素的值,元素不出栈。
int GetTop(PSeqStack SS, ElemType *ee);
//SeqStac.cpp顺序栈
#include "SeqStack.h"
// 顺序栈SS的初始化操作。
Status InitStack(PSeqStack SS)
{
Clear(SS);
return OK;
}
// 销毁顺序栈SS。
void DestroyStack(PSeqStack SS)
{
// 静态顺序栈无需释放内存,不需要销毁操作。
Clear(SS); // 清空顺序栈。
return;
}
// 元素入栈,返回值:0-失败;1-成功。
int Push(PSeqStack SS, ElemType *ee)
{
if ((SS == NULL) || (ee == NULL)) return ERROR; // 检查空指针。
if (IsFull(SS) == 1)
{
printf("顺序栈已满,不能插入。\n"); return 0;
}
SS->top++; // 栈指针先加1。
memcpy(&SS->data[SS->top], ee, sizeof(ElemType)); // 用数组的下标访问。 // memcpy(SS->data+SS->top,ee,sizeof(ElemType)); // 采用指针运算也可以。
return OK;
}
// 元素出栈,返回值:0-失败;1-成功。
int Pop(PSeqStack SS, ElemType *ee)
{
if ((SS == NULL) || (ee == NULL)) return ERROR; // 检查空指针。
if (SS->top == -1) { printf("栈为空。\n"); return ERROR; }
memcpy(ee,&SS->data[SS->top], sizeof(ElemType));
SS->top--;
return OK;
}
// 求顺序栈的长度,返回值:栈SS中元素的个数。
int Length(PSeqStack SS)
{
if (SS == NULL) return 0; // 检查空指针。
return SS->top + 1;
}
// 清空顺序栈。
void Clear(PSeqStack SS)
{
if (SS == NULL) return; // 检查空指针。
SS->top = -1; // 栈顶指针置为-1。
memset(SS->data, 0, sizeof(ElemType)*MAXSIZE); // 数组元素清零。
}
// 判断顺序栈是否为空,返回值:1-空,0-非空或失败。
int IsEmpty(PSeqStack SS)
{
if (SS == NULL) return 0; // 检查空指针。
if (SS->top == -1) return 1;
return 0;
}
// 判断顺序栈是否已满,返回值:1-已满,0-未满或失败。
int IsFull(PSeqStack SS)
{
if (SS == NULL) return ERROR; // 检查空指针。
if (SS->top >= MAXSIZE)
{
return OK;
}
return 0;
}
// 打印顺序栈中全部的元素。
void PrintStack(PSeqStack SS)
{
if (SS == NULL) return; // 检查空指针。
if (SS->top == -1) { printf("栈为空。\n"); return ; }
int kk;
for (kk = 0; kk <= SS->top; kk++)
{
printf("SS[%d],value=%d\n", kk, SS->data[kk]);
// 用数组的下标访问。
// printf("SS[%d],value=%d\n",kk,*(SS->data+kk)); // 采用指针运算也可以。
}
}
// 获取栈顶元素,返回值:0-失败;1-成功。
// 只查看栈顶元素的值,元素不出栈。
int GetTop(PSeqStack SS, ElemType *ee)
{
if (SS == NULL) return ERROR; // 检查空指针。
if (SS->top == -1) { printf("栈为空。\n"); return ERROR; }
memcpy(ee, &SS->data[SS->top], sizeof(ElemType));
// 用数组的下标访问。
// memcpy(ee,SS->data+SS->top,sizeof(ElemType)); // 采用指针运算也可以。
return OK;
}
void test01()
{
SeqStack SS;
InitStack(&SS);
printf("栈的长度是%d\n", Length(&SS));
ElemType ee; // 创建一个数据元素。
printf("元素(1、2、3、4、5、6、7、8、9、10)入栈。\n");
ee = 1; Push(&SS, &ee);
ee = 2; Push(&SS, &ee);
ee = 3; Push(&SS, &ee);
ee = 4; Push(&SS, &ee);
ee = 5; Push(&SS, &ee);
ee = 6; Push(&SS, &ee);
ee = 7; Push(&SS, &ee);
ee = 8; Push(&SS, &ee);
ee = 9; Push(&SS, &ee);
ee = 10; Push(&SS, &ee);
printf("栈的长度是%d\n", Length(&SS));
// 只查看栈顶元素的值,元素不出栈。
if (GetTop(&SS, &ee) == 1) printf("栈顶的元素值为%d\n", ee);
PrintStack(&SS);
if (Pop(&SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(&SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(&SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(&SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(&SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(&SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(&SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(&SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(&SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(&SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(&SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(&SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
}
int main()
{
test01();
system("pause");
return EXIT_SUCCESS;
}
链栈
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
//Status 是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef int ElemType;
typedef struct SNode
{
ElemType data; // 链栈中的元素。
struct SNode *next; // 指向下一个结点的指针。
}SNode, *LinkStack;
// 链栈SS的初始化操作,分配头结点,返回头结点的地址。
SNode *InitStack();
// 销毁链栈SS。
void DestroyStack(LinkStack SS);
// 元素入栈,返回值:0-失败;1-成功。
int Push(LinkStack SS, ElemType *ee);
// 元素出栈,返回值:0-失败;1-成功。
int Pop(LinkStack SS, ElemType *ee);
// 求链栈的长度,返回值:栈SS中元素的个数。
int Length(LinkStack SS);
// 清空链栈。
void Clear(LinkStack SS);
// 判断链栈是否为空,返回值:1-空,0-非空或失败。
int IsEmpty(LinkStack SS);
// 打印链栈中全部的元素。
void PrintStack(LinkStack SS);
// 获取栈顶元素,返回值:0-失败;1-成功。
// 只查看栈顶元素的值,元素不出栈。
int GetTop(LinkStack SS, ElemType *ee);
#include "LinkStack.h"
// 链栈SS的初始化操作,分配头结点,返回头结点的地址。
SNode *InitStack()
{
SNode * SS = new SNode;
if (SS == NULL) return NULL; // 内存不足,返回失败。
SS->next = NULL; // 头结点的下一结点暂时不存在,置空。
return SS;
}
// 销毁链栈SS。
void DestroyStack(LinkStack SS)
{
if (SS == NULL) return ;
Clear(SS);
if (SS)
{
delete SS;
}
}
// 元素入栈,返回值:0-失败;1-成功。
int Push(LinkStack SS, ElemType *ee)
{
if ((SS == NULL) || (ee == NULL)) return 0; // 检查空指针。
// 内存不足,返回失败。
// 考虑数据元素为结构体的情况,这里采用了memcpy的方法而不是直接赋值
SNode * p = new SNode;
memcpy(&p->data, ee, sizeof(ElemType));
p->next = SS->next;
SS->next = p;
return OK;
}
// 元素出栈,返回值:0-失败;1-成功。
int Pop(LinkStack SS, ElemType *ee)
{
if ((SS->next == NULL) || (ee == NULL)) return 0; // 检查空指针。
SNode * p = SS->next;
memcpy( ee,&p->data, sizeof(ElemType));
SS->next = p->next;
delete p;
return OK;
}
// 求链栈的长度,返回值:栈SS中元素的个数。
int Length(LinkStack SS)
{
if ((SS->next == NULL) ) return 0; // 检查空指针。
int i = 0;
SNode * p = SS->next;
while (p)
{
i++;
p = p->next;
}
return i;
}
// 清空链栈。
void Clear(LinkStack SS)
{
if (SS == NULL) return;
SNode * p = SS->next;
SNode * q;
while (p)
{
q = p->next;
delete p;
p = q;
}
SS->next = NULL;
}
// 判断链栈是否为空,返回值:1-空,0-非空或失败。
int IsEmpty(LinkStack SS)
{
if (SS == NULL)
{
return -1;
}
if (SS->next)
{
return 0;
}
return 1;
}
// 打印链栈中全部的元素。
void PrintStack(LinkStack SS)
{
if (SS == NULL) return;
if (SS->next == NULL) { printf("栈为空。\n"); return; }
int kk = 0;
SNode *pp = SS->next; // 从第1个结点开始。
while (pp != NULL)
{
printf("SS[%d],value=%d\n", kk++, pp->data);
pp = pp->next;
}
}
// 获取栈顶元素,返回值:0-失败;1-成功。
// 只查看栈顶元素的值,元素不出栈。
int GetTop(LinkStack SS, ElemType *ee)
{
if (SS == NULL) return ERROR;
if (SS->next == NULL) { printf("栈为空。\n"); return ERROR; }
memcpy(ee, &SS->next->data, sizeof(ElemType));
return OK;
}
void test01()
{
LinkStack SS; // 创建链栈。
SS = InitStack(); // 初始化链栈。
printf("栈的长度是%d\n", Length(SS));
ElemType ee; // 创建一个数据元素。
printf("元素(1、2、3、4、5、6、7、8、9、10)入栈。\n");
ee = 1; Push(SS, &ee);
ee = 2; Push(SS, &ee);
ee = 3; Push(SS, &ee);
ee = 4; Push(SS, &ee);
ee = 5; Push(SS, &ee);
ee = 6; Push(SS, &ee);
ee = 7; Push(SS, &ee);
ee = 8; Push(SS, &ee);
ee = 9; Push(SS, &ee);
ee = 10; Push(SS, &ee);
printf("栈的长度是%d\n", Length(SS));
if (GetTop(SS, &ee) == 1) printf("栈顶的元素值为%d\n", ee);
PrintStack(SS);
if (Pop(SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
if (Pop(SS, &ee) == 1) printf("出栈的元素值为%d\n", ee);
// 销毁链栈SS。
DestroyStack(SS); SS = 0; // 销毁链栈后把SS置为空,防止野指针。
}
int main()
{
test01();
system("pause");
return EXIT_SUCCESS;
}```