栈:允许插入和删除的一段叫做栈顶,不允许的一端称为栈底
遵循先进后出
栈中获取元素只能通过栈顶指针取栈顶元素
链式栈的重要操作:
头部重要声明
typedef struct Node* pNode;
typedef struct Stack* LinkStack;
struct Node
{
int date;//数据存储
pNode next;//这是一个名叫next 的指针变量
};
struct Stack//该结构体记录栈的栈顶信息和存储数据的多少
{
pNode top;//
int size;
};
创建栈函数
LinkStack Create() //该函数为stack结构体分配空间,返回stack类型的指针
{
LinkStack lstack=(Linkstack)malloc(sizeof( struct Stack));//首先先分配struct该结构体的空间
if(lstack !=NULL)
{
lstack->top=NULL;
lstack->size=0;
}
return lstack;
}
进栈操作函数
pNode getTop(LinkStack lstack)//获取栈顶元素的函数
{
return lstack->top;
}
int Push(LinkStack lstack,int val)//该函数返回整型是用来判断是否进栈成功,两个参数是,链表和插入值
{
Pnode node=(pNode)malloc(sizeof(struct Node));//分配一个节点空间;
if(node!=0)
{
node->data=val;
node->next=getTop(lstack);
lstack->top=node;
lstack->size++;
}
return 1;
}
出栈操作
pNode Pop(LinkStack lstack)//返回被弹出的那个元素
{
pNode node =lstack->top;
lstack->top=;lstack->top>next;
lstack->size--;
return node;
}
销毁栈操作函数
void Destory(LinkStack lstack)
{
pNode temp;
do{
temp=Pop(lstack);
free(temp);
}while(lstack->sze>0);
printf("销毁成功\n");
}
栈的应用
四则运算:
中缀转后缀:
-
对于数字直接输出
-
对于符号:左括号:进栈,不管栈中是否有元素(优先级最低,直接进栈)
运算符:栈为空,直接进栈。若栈中有元素,则栈顶符号进行优先级比较:优先级高的先进栈。
若符号优先级低,将栈顶号弹出,之后使新符号进栈
右括号:不断将栈顶符号弹出输出,直接匹配大左括号,再接着读取下一个符号需注意,左右括号匹配完成即可,并不讲括号输出; -
遍历结束,将栈中所有符号弹出并输出
例:1+3*(2+5)
(1) 遍历字符串,第一个读到的字符 ‘1’ ,是数字直接输出,结果:1
(2) '+'进栈,暂时结果:1
(3) ‘3’直接输出,暂时结果:13
(4) * 优先级高于现在栈顶的符号,直接进栈,暂时结果:13
(5) ‘(’直接进栈
(6) 2输出,结果:132
(7) + 优先级比‘(’高,进栈;
(8) 5,输出,结果:1235
(9) ) 进栈,开始弹栈,直到遇到左括号为止,弹完还没就报错;结果:1235+
(10)遍历结束了,可以开始弹栈,结果:1235+*+
后缀表达式运算:
- 数字直接进栈
- 符号:先从栈中弹出右操作数,再弹出左操作数,再将运算结果进栈
- 遍历结束,栈中唯一数字就是结果
例:1325+*+
2+5=7进栈;结果:137
3×7=21进栈,结果:121
1+21=22进栈,结果:22
队列
- 队列和栈一样,也是一种受限的线性表
- 允许删除的队头,允许插入的是队尾
- 遵循:先进先出
- 队列中会有一个指针指向对头,称为队头指针,同时也有一个队尾指针
- 真溢出:是没空间供新元素进入队列
- 假溢出:就尾指针rear 指向了数组的最大下标,但是随着头指针不断有元素出队,但头指针front向后移;比如:本该front与rear间有48个元素,但是现在只有38,证明是有空间但指针原因造成假象的溢出
循环队列:头指针和尾指针相连
之前:front=rear 来判断队列是否为空,现在在循环队列中,他也可以代表队满,为了解决这个问题,循环队列约定:少用了一个元素空间,当队尾表示rear在队头标识front的上一个元素空间,则队满;
- 对空:front==rear为真时
- 队满:(rear+1)%MAXSIZE==front 为真时 //MAXSIZE是队列的容量大小
- 每次移动都要对队列容量取模:front=(front+1)%MAXSIZE,rear=(rear+1)%MAXSIZE
-队列的长度:(rear+MAXSIZE-front)%MAXSIZE
#define MAXSIZE 50
typedef struct CirQueue * SeqQueue
struct CirQueue
{
int front;
int rear;
int data[MAXSIZE];
}
入队代码:
void Insert(SeqQueue cq,int val)
{
if((cq->rear+1)%MAXSIZE==cq->front)
{printf("队列满了");return;}
if(Isempty(cq))
{
cq->front=cq->rear=0;
cq->data[cq->rear]=val;
cq->rear++;
}
else
{
cq->data[cq->rear]=val;
ca->rear=(cq->rear+1)%MAXSIZE;
}
}
出队代码:
int del(SeqQueue cq)
{
int temp;
if(Isempty(cq))
{
printf("队列为空\n");
return;
}
temp=cq->data[cq->front];
cq->front=(cq->rear+1)%MAXSIZE;
return temp;
}