栈与队列
线性结构两种常见的应用之一- – -- – -栈
定义:一种可以实现“先进后出”的存储结构,类似于箱子
分类:静态栈----顺序表
动态栈—链式
算法:压栈 出栈
应用:函数调用 中断、表达式求值、内存分配、缓存处理、迷宫等
# include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct Node
{
int data;
struct Node* pNext;
}Node,* PNODE;
typedef struct Stack {
PNODE pTop;
PNODE pBottom;
}STACK,* PSTACK;
void init(PSTACK pS) {
pS->pTop = (PNODE)malloc(sizeof(Node));
if (pS->pTop == NULL) {
printf("失败");
exit(-1);
}
else {
pS->pBottom = pS->pTop;
pS->pTop->pNext = NULL;
}
}
void push(PSTACK pS, int val) {
PNODE pNew = (PNODE)malloc(sizeof(Node));
if (pNew == NULL) {
printf("失败");
exit(-1);
}
else
{
pNew->data = val;
pNew->pNext = pS->pTop;
pS->pTop = pNew;
}
}
void traverse(PSTACK pS) {
PNODE p = pS->pTop;
while (p != pS->pBottom) {
printf("%d ", p->data);
p = p->pNext;
}
}
bool empty(PSTACK pS) {
if (pS->pTop == pS->pBottom) {
return true;
}
else {
return false;
}
}
bool pop(PSTACK pS, int * pVal) {
if (empty(pS)) {
return false;
}
else
{
PNODE r = pS->pTop;
* pVal = r->data;
pS->pTop = r->pNext;
free(r);
r = NULL;
return true;
}
}
void clear(PSTACK pS) {
if (empty(pS)) {
return;
}
else {
PNODE p, q;
q = NULL;
p = pS->pTop;
while (p != pS->pBottom) {
q = p->pNext;
free(p);
p = q;
}
pS->pTop = pS->pBottom;
}
}
void popoone(PSTACK pS, int* pVal) {
if (pop(pS, pVal)) {
printf("出栈成功,出栈元素为 %d ", * pVal);
}
else
{
printf("出栈失败\n");
}
}
int main(void) {
STACK S;
int val;
init(&S);
push(&S, 1);
push(&S, 2);
push(&S, 3);
push(&S, 4);
push(&S, 5);
push(&S, 6);
push(&S, 7);
push(&S, 8);
push(&S, 9);
push(&S, 10);
traverse(&S);//类似于出栈
printf("\n");
popoone(&S, &val);
popoone(&S, &val);
popoone(&S, &val);
printf("\n");
traverse(&S);//类似于出栈
//clear(&S);
return 0;
}
线性结构两种常见的应用之二- – -- – -队列
定义:一种可以实现“先进先出”的存储结构,类似于排队
分类:链式队—列用链表实现
静态队列---用数组实现(通常都必须是循环队列)
循环队列的讲解:
1、静态队列为什么必须是循环队列?
2、循环队列需要几个参数来确定?
3、循环队列各个参数的含义?
front 、rear不同场合有不同意义
1)、队列初始化:front与rear的值都为0;
2)、队列非空:front代表队列第一个元素,rear代表队列最后一个有效元素的下一个;
3)、队列空:front与rear值相等但不一定为0。
4、循环队列伪入队算法讲解?
将值存入r所代表的位置;
r=(r+1)%数组长度;
5、循环队列伪出队算法讲解?
f=(f+1)%数组长度;
6、如何判断循环队列是否为空?
如果front与rear的值相等,即为空
7、如何判断循环队列是否为满?
两种方式:
1、增加一个表示符;2、少用一个元素;(r+1)%长度==f则满。
算法:出队,入队
具体应用:所有和时间有关的操作都有类似的
# include <stdio.h>
# include<malloc.h>
typedef struct Queue
{
int* pBase;
int front;
int rear;
}QUEUE;
void init(QUEUE * pQ ) {
pQ->pBase = (int*)malloc(sizeof(int) * 6);
pQ->front = 0;
pQ->rear = 0;
}
bool full_queue(QUEUE* pQ) {
if ((pQ->rear + 1) % 6 == pQ->front)
return true;
else return false;
}
bool en_queue(QUEUE* pQ,int val) {
if (full_queue(pQ)) {
return false;
}
else {
pQ->pBase[pQ->rear] = val;
pQ->rear = (pQ->rear + 1) % 6;
return true;
}
}
void traverse_queue(QUEUE* pQ) {
int i = pQ->front;
while (i!=pQ->rear) {
printf("%d ", pQ->pBase[i]);
i=(i+1)%6;
}
}
bool empty_queue(QUEUE* pQ) {
if (pQ->front == pQ->rear)
return true;
else return false;
}
bool out_queue(QUEUE* pQ,int * pVal) {
if (empty_queue(pQ)) {
return false;
}
else {
*pVal = pQ->pBase[pQ->front];
pQ->front = (pQ->front + 1) % 6;
return true;
}
}
void main() {
QUEUE Q;
int val;
init(&Q);
en_queue(&Q, 1);
en_queue(&Q, 2);
en_queue(&Q, 3);
en_queue(&Q, 4);
en_queue(&Q, 5);
en_queue(&Q, 6);
traverse_queue(&Q);
printf("\n");
if (out_queue(&Q, &val))
{
printf("出队成功,出队元素为%d ", val);
printf("\n");
}
else {
printf("出队失败\n");
}
traverse_queue(&Q);
}