数据结构(C)-----栈和队列

目录

一丶栈和队列

1.1 栈的定义

1.2 栈的顺序存储结构

1.3 栈的创建

1.4 栈的操作

1.4.1 入栈操作

1.4.2 出栈操作

1.4.2 栈的清空

1.4.3 栈的销毁

1.4.4 栈的当前容量

1.5 例题

1.6 栈的链式存储结构(了解)

1.7 栈的操作

1.7.1 进栈操作

1.7.2 出栈操作

1.8 例题

1.9 队列的定义

2.1 对列的链式存储结构

2.2 队列的创建

2.3 队列的操作

2.3.1 入队列

2.3.2 出队列

2.3.3 销毁队列

2.4 队列的顺序存储结构(了解)

2.5 定义循环队列

2.6 初始化循环队列

2.7 入队列操作

2.8 出队列操作


一丶栈和队列

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;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值