目录
一丶栈和队列
1.1 栈的定义
官方定义:
栈(Stack)是一个后进先出(Last in first out , LIFO)的线性表,它要求只在表尾进行删除和插入操作。
注意:
一栈的元素必须“后进先出” 一栈的操作只能在这个线性表的表尾进行 一注 : 对于栈来说, 这个表尾称为栈的栈顶(top)相应的表头称为栈底(bottom))
1.2 栈的顺序存储结构
typedef struct
{
ElemType *base; //指向栈底的指针变量
ElemType *top; //指向栈顶的指针变量
int stackSize; //指示栈的当前可使用的最大容量
}sqStack;
1.3 栈的创建
#define STACK_INIT_SIZE 100
initStack(sqStack *s)
{
s->base=(ElemType*)malloc( STACK_INIT_SIZE*sizeof(ElemType));
if(!s->base) //申请空间失败就退出
exit(0);
s->top=s->base;//最开始,栈顶就是栈底
s->stackSize=STACK_INIT_SIZE;
}
1.4 栈的操作
1.4.1 入栈操作
#define Append 10
Push(sqStack *s,ElemType e)
{
//如果栈满,追加空间
if(s->top - s->base >= s->stackSize)
{
s->base = (ElemType*)realloc(s->base,(s->stackSize + Append )* sizeof(ElemType));
if(!s->base)
{
exit(0);
}
s->top = s->base + s->stackSize; //设置栈顶
s->stackSize = s->stackSize + Append //设置栈的最大容量
}
*(s->top) = e;
s->top++;
}
1.4.2 出栈操作
Pop(sqStack *s,ElemType *e)
{
if(s->top == s->base) //栈空
return;
*e=*--(s->top);
}
1.4.2 栈的清空
所谓清空一个栈,就是将栈中的元素全部作废,但栈本身物理空间并不发生改变(不是销毁)。
ClearStack(sqStack *s)
{
s->top = s->base;
}
1.4.3 栈的销毁
DestoryStack(sqStack *s)
{
int i,len;
len=s->stackSize;
for(i=0;i<len;i++)
{
free(s->base);
s->base++;
}
s->base = s->top = NULL;
s->stackSize = 0;
}
1.4.4 栈的当前容量
int Stacklen(sqStack s)
{
return (s.top-s.base);//中间隔了几个元素
}
1.5 例题
题目描述:利用栈的特点,将二进制数转化为十进制数。
#include<stdio.h>
#include<stdlib.h>
#include<Math.h>
#define STACK_INIT_SIZE 20
#define STACKINCREMENT 10
typedef char ElemType;
typedef struct
{
ElemType* top;
ElemType* base;
int stackSize;
}sqStack;
void InitStack(sqStack* s)
{
s->base = (ElemType*)malloc(STACK_INIT_SIZE * sizeof(ElemType));
if (!s->base)
{
exit(0);
}
s->base = s->top;
s->stackSize = STACK_INIT_SIZE;
}
void Push(sqStack* s, ElemType e) //入栈操作
{
if (s->top - s->base >= s->stackSize)
{
s->base = (ElemType*)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
if (!s->base)
{
exit(0);
}
s->top = s->base + s->stackSize;
s->stackSize = s->stackSize + STACKINCREMENT;
}
/*
printf("栈以满,无法再储存元素");
*/
*(s->top) = e;
s->top++;
}
ElemType Pop(sqStack* s, ElemType* e) //出栈操作
{
if (s->top == s->base)
{
return;
}
*e = *--(s->top);
}
int Stacklen(sqStack s) //返回栈的当前容量
{
return (s.top - s.base);
}
int main()
{
ElemType c;
sqStack s;
int len, i, sum = 0;
printf("请输入二进制数\n");
InitStack(&s);
scanf_s("%c", &c);
while (c != '#')
{
Push(&s, c);
scanf_s("%c", &c);
}
len = Stacklen(s);
printf("栈的当前容量是%d",len);
for (i = 0; i < len; i++)
{
Pop(&s, &c);
sum = sum + (c - 48) * pow(2, i);
}
printf("转化为十进制数为: %d", sum);
return 0;
}
1.6 栈的链式存储结构(了解)
teypedef struct StackNode
{
ElemType data; //存放栈的数据
struct StackNode *next
}StackNode, *LinkStackPtr
typedef struct LinkStack
{
LinkStackPrt top; //top指针
int count; //栈元素计数器
}
1.7 栈的操作
1.7.1 进栈操作
Status Push(LinkStack*s, ElemType e)
{
LinkStackPtr p= (LinkStackPtr) malloc(sizeof(StackNode));
p->data = e;
p->next = s->top;
s->top = p;
s->count++;
return OK;
}
1.7.2 出栈操作
Status Pop(LinkStack *s,ElemType *e)
{
LinkStackPtr p;
if(StackEmpty(*s)) //判断是否为空栈
return ERROR;
*e= s->top->data;
p= s->top;
s->top = s->top->next;
free(p);
s->count--;
return OK;
}
1.8 例题
逆波兰计算器
1.9 队列的定义
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。 与栈相反,队列是一种先进先出(First In First Out , FIFO)的线性表。
2.1 对列的链式存储结构
typedef struct QNode
{
ElemType data;
struct QNofe *next;
}QNode,*QueuePrt;
typedef struct
{
QueuePrt front,rear;//队头丶 尾指针
}LinkQueue;
2.2 队列的创建
initQueue(LinkQueue *q)
{
q->front=q->rear=(QueuePtr)malloc(sizeof(QNode));
if( !q->front )
exit(0);
q->front->next = NULL;
}
2.3 队列的操作
2.3.1 入队列
InsertQueue(LinkQueue *q,ElemType e)
{
QueuePtr p;
p= (QueuePtr)malloc(sizeof(QNode));
if(p== NULL )
exit(0);
p->data = e;
p->next =NULL;
q->rear->next = p;
q->rear = p;
}
2.3.2 出队列
DeleteQueue(LinkQueue *q,ELemype *e)
{
QueuePtr p;
if( q->front == q->rear )
return;
P=q->front->next;*e = p->data;
q->front->next= p->next;
if(q->rear == p)
q->rear = q->front;
free(p);
}
2.3.3 销毁队列
DestroyQueue(LinkQueue *q)
{
while( q->front )
{
q->rear = q->front->next;
free( q->front );
q->front = q->rear;
}
}
2.4 队列的顺序存储结构(了解)
为了解决假溢出,采用循环队列
2.5 定义循环队列
#define MAXSIZE 100
typedef struct
{
ElemType *base; //用于存放内存分配基地址
//这里你也可以用数组存放
int front;
int rear;
}
2.6 初始化循环队列
initQueue(cycleQueue *q)
{
q->base = (ElemType)malloc(MAXSIZE * sizeof(ElemType));
if( !q->base )
exit(0);
q->front = q->rear = 0;
}
2.7 入队列操作
InsertQueue(cycleQueue *q ,ElemType e)
{
if((q->rear+1)%MAXSIZE == q->front )
return; //队列已满
q->base[q->rear] = e;
q->rear = (q->rear+1)% MAXSIZE;
}
2.8 出队列操作
DeleteQueue(cycleQueue *q ,ElemType *e)
{
if( q->front ==q->rear
return ; //队列为空
*e =q->base[q->front];
q->front = (q->front+1)% MAXSIZE;
}