栈与队列
栈的定义:
栈是限定在表尾进行插入和删除的线性表,表尾具有特殊的意义,表尾叫做栈顶,表头叫做栈底,具有后进先出的特点,其称之为LIFO结构(last in first out),从逻辑结构上看,与线性表相同,为一对一的关系,存储结构用顺序栈或链栈存储既可,但是以顺序栈最为常见
队列的定义:
队列是一种先进先出的线性结构(first in firt out),允许插入的一头为队尾,允许删除的一头为队头
栈的基本操作:
定义文件
#pragma once
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OK 1
#define ERROR -1
typedef struct SqStack{
int* base;
int* top;
int stacksize; //当前已经分配的栈的空间
}SqStack;
int InitStack(SqStack& S); //成功返回OK,失败返回ERROR
int DestroyStack(SqStack& S); //销毁成功返回OK,失败返回ERROR
int ClearStack(SqStack& S); //清空栈中的所有元素
bool StackEmpty(SqStack& S); //判断是否为空栈
int StackLength(SqStack& S); //返回栈的个数
int Push(SqStack& S, int e); //压栈
int Pop(SqStack& S, int& e); //弹栈
int GetTop(SqStack& S, int& e); //得到栈顶
#include <stdio.h>
#include <stdlib.h>
#include "structure.h"
int main() {
SqStack S;
InitStack(S);
Push(S, 1);
Push(S, 5);
Push(S, 7);
int len = StackLength(S);
printf("%d\n", len);
int e;
Pop(S, e);
printf("%d\n", e);
GetTop(S, e);
printf("%d\n", e);
return 0;
}
int InitStack(SqStack& S) {
S.base = (int*)malloc(sizeof(int) * STACK_INIT_SIZE);
if (!S.base)
return ERROR;
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}
int DestroyStack(SqStack& S) {
if (!S.base) {
free(S.base); //释放指针指向的空间
S.stacksize = 0; //将栈的长度设置为0
S.base = S.top = NULL; //防止野指针的产生
}
return OK;
}
int ClearStack(SqStack& S) {
if (S.base) {
S.top = S.base; //恢复初始化的状态
}
return OK;
}
bool StackEmpty(SqStack& S) {
if (S.base) {
if (S.base == S.top) {
return true;
}
return false;
}
}
int StackLength(SqStack& S) {
/*
* 思路:头指针减去尾指针的个数就是栈的个数
*/
if (S.base) {
return S.top - S.base;
}
return ERROR;
}
int Push(SqStack& S, int e) {
/*
* 压栈操作:
* 1.判断栈是不是为满
* 2.如果为满重新分配内存(增加内存)
* 3.如果不为满则将S.top指向的空间的值设置为e,并且S.top++
*/
if (S.base) {
//栈满的情况
if (S.top - S.base >= S.stacksize) {
S.base = (int*)realloc(S.base,sizeof(int) * (S.stacksize + STACKINCREMENT));
if (!S.base)
return ERROR;
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top++ = e;
return OK;
}
}
int Pop(SqStack& S, int& e) {
/*
* 1.首先判断栈是否为空,如果为空,返回ERROR
* 2.如果不为空,top--,e = *top
*/
if (S.base) {
if (S.base == S.top)
return ERROR;
e = *(--S.top);
}
return OK;
}
int GetTop(SqStack& S, int& e) {
if (S.top == S.base)
return ERROR;
e = *(S.top - 1);
return OK;
}
栈的应用:
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "structure.h"
int main() {
SqStack OPTR, OPND; //OPTR为运算符栈,OPND为操作数栈
InitStack(OPTR);
InitStack(OPND);
char sum = EvaluateExpression(OPTR,OPND);
printf("%d", sum);
return 0;
}
int InitStack(SqStack& S) {
S.base = (char*)malloc(sizeof(char) * STACK_INIT_SIZE);
if (!S.base)
return ERROR;
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}
int Push(SqStack& S, char c) {
if (S.base) {
if (S.top - S.base >= S.stacksize) {
S.base = (char*)realloc(S.base, sizeof(char) * (S.stacksize * STACKINCREAMENT));
if (!S.base)
return ERROR;
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREAMENT;
}
*S.top++ = c;
return OK;
}
return ERROR;
}
int Pop(SqStack& S, char& c) {
if (S.base) {
if (S.base == S.top)
return ERROR;
else {
c = *(--S.top);
return OK;
}
}
return ERROR;
}
char GetTop(SqStack& S) {
if (S.base) {
if (S.base == S.top)
return NULL;
return *(S.top - 1);
}
return NULL;
}
int EvaluateExpression(SqStack& OPTR, SqStack& OPND) {
char c;
char x; //弹出相同等级的操作符
Push(OPTR, '#');
c = getchar(); //获取缓存区的第一个字符
while (c != '#' || GetTop(OPTR) != '#') {
if (!IN(c)) //如果不是操作符将其压入操作数栈
{
Push(OPND, c);
c = getchar(); //继续从缓存区中取数据
}
else
switch (Precede(GetTop(OPTR), c)) {
case '<':
//栈顶元素的优先级低压栈
Push(OPTR, c);
c = getchar();
break;
case '=':
//去除括号
Pop(OPTR, x);
c = getchar();
break;
case '>':
//弹出操作符号
char theta, b, a;
Pop(OPTR, theta);
Pop(OPND, a);
Pop(OPND, b);
Push(OPND, operate(a, theta, b));
break;
default:
break;
}
}
return GetTop(OPND);
}
bool IN(char c) {
for (int i = 0; i < 7; i++) {
if (c == allOperator[i])
return true;
}
return false;
}
char Precede(char c1, char c2) {
//获得c1,c2的优先级等级
int c1Prior = getPriorNum(c1);
int c2Prior = getPriorNum(c2);
if (c1Prior > c2Prior)
return '>';
else if (c1Prior == c2Prior)
return '=';
else
return '<';
}
int getPriorNum(char c) {
int priorNum;
switch (c)
{
case '#':
priorNum = -1;
break;
case '(':
priorNum = 0;
break;
case '+':
priorNum = 1;
break;
case '-':
priorNum = 1;
break;
case ')':
priorNum = 2;
break;
case '/':
priorNum = 2;
break;
case '*':
priorNum = 3;
break;
default:
break;
}
return priorNum;
}
char operate(char a, char t, char b) {
int sum;
int c = a - '0';
int d = b - '0'; //将char转化为int
switch (t)
{
case '+': sum = c + d; break;
case '-': sum = c - d; break;
case '*': sum = c * d; break;
default: sum = c / d;
}
char strSum = sum + '0'; //将int转化为char
return sum;
}
数据类型定义:
#pragma once
#define STACK_INIT_SIZE 100
#define STACKINCREAMENT 10
#define OK 1
#define ERROR -1
typedef struct SqStack{
char* top;
char* base;
int stacksize; //堆栈的大小
}SqStack;
char allOperator[] = { '+' , '-' , '*' , '/' ,'(' , ')' , '#' }; //把符号转换成字符数组
int InitStack(SqStack& S); //初始化栈
int Push(SqStack& S,char c); //压栈
int Pop(SqStack& S, char& c); //出栈
char GetTop(SqStack& S); //得到栈顶的元素
/*
* 比较操作符的优先级
*/
char Precede(char c1, char c2);
int getPriorNum(char c); //获得优先级等级操作符
char operate(char a, char t, char b);
bool IN(char c);
int EvaluateExpression(SqStack& OPTR, SqStack& OPND);
链式队列
结构体的定义
#pragma once
//定义队列的链式存储结构
//结点的定义
typedef struct QNode {
int data; //data数据域
struct QNode* next;
}QNode,*QueuePtr;
//首尾指针的定义
typedef struct {
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
void InitQueue(LinkQueue& Q); //队列的初始化
void EnQueue(LinkQueue& Q,int data); //向队列中插入一个元素
void DuQueue(LinkQueue& Q, int& data); //删除队列的头部元素
void DestroyQueue(LinkQueue& Q); //销毁队列
void DisplayQueue(LinkQueue& Q); //展现队列中所有元素
方法的实现
#include <stdio.h>
#include <stdlib.h>
#include "structure.h"
int main() {
LinkQueue Q;
int a;
InitQueue(Q);
EnQueue(Q, 1);
EnQueue(Q, 2);
EnQueue(Q, 3);
DisplayQueue(Q);
DuQueue(Q, a);
printf("%d", a);
return 0;
}
void InitQueue(LinkQueue& Q) {
Q.front = Q.rear = (QNode*)malloc(sizeof(QNode)); //创建首元结点,并将首尾指针指向首尾结点
if (!Q.front)
exit(-1);
Q.front->next = NULL; //将第一个结点的指针域置为空
}
void EnQueue(LinkQueue& Q, int data) {
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
p->data = data; //给数据域进行赋值
p->next = NULL;
Q.rear->next = p;
Q.rear = p; //将队尾指针指向最后一个结点
}
void DuQueue(LinkQueue& Q, int& data) {
if (Q.front == Q.rear)
exit(-1); //如果队列是空队列,则无法弹出,报错
QueuePtr p = Q.front->next;
data = p->data;
Q.front->next = p->next; //将首指针指向删除结点的下一个结点
if (Q.rear == p)
Q.rear = Q.front;
free(p);
}
void DestroyQueue(LinkQueue& Q) {
//销毁队列Q
while (Q.front)
{
Q.rear = Q.front->next;
free(Q.front);
Q.front = Q.rear;
}
}
void DisplayQueue(LinkQueue& Q) {
if (Q.rear == Q.front)
exit(-1);
QueuePtr p = Q.front->next;
while (Q.rear->next != p)
{
printf("%d\n", p->data);
p = p->next;
}
}

1160

被折叠的 条评论
为什么被折叠?



