• DS博客作业02--栈和队列


    这个作业属于哪个班级 数据结构--网络2011/2012
    这个作业的地址 DS博客作业02--栈和队列
    这个作业的目标 学习栈和队列的结构设计及运算操作
    姓名 吴俊豪

    0.PTA得分截图

    1.本周学习总结

    1.1栈

    顺序栈

    结构:


    如图所示,顺序栈即一堆按照顺序排列的,拥有连续内存地址的储蓄结构的栈,数据由栈顶进入和导出,因此其对数据读取(尤其是栈底数据)时相较于数组和链表的效率略低,但其仅能从栈顶进出的特性对一些特殊(配对类)的问题效果拔群.

    操作函数

    结构体创建:
    typedef int Position;
    typedef struct SNode *PtrToSNode;
    struct SNode {
        ElementType *Data;  /* 存储元素的数组 */
        Position Top;       /* 栈顶指针       */
        int MaxSize;        /* 堆栈最大容量   */
    };
    typedef PtrToSNode Stack;
    
    创建并初始化顺序栈
    Stack CreateStack( int MaxSize )
    {
        Stack S = (Stack)malloc(sizeof(struct SNode));
        S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
        S->Top = 0;//栈顶
        S->MaxSize = MaxSize;
        return S;
    }
    
    入栈与出栈
    bool Push(Stack S, ElementType X)//入栈
    {
        if (S->Top == S->MaxSize)//满栈
        {
            printf("Stack Full
    ");
            return false;
        }
        S->Top++;
        S->Data[S->Top] = X;
        return true;
    }
    
    ElementType Pop(Stack S)//出栈
    {
        int e;
        if (S->Top == 0)空栈
        {
            printf("Stack Empty
    ");
            return ERROR;
        }
        e = S->Data[S->Top];
        S->Top--;
        return e;
    }
    

    注:入栈记得检查栈满,出栈记得检查栈空.

    链栈

    结构


    链栈,顾名思义,就是和单链表长的八成像的栈结构,区别在于只能在栈顶进行数据操作.

    操作函数

    创建结构体
    typedef struct SNode          //定义链栈结点类型
    {
        ElemType data;
        struct SNode *next;        //指向后继结点
    } LNode,*LinkStack;
    
    创建并初始化链栈
    
    bool InitStack(LinkStack &S)
    
    {
        S=NULL;
        return true;
    }
    

    入栈与出栈

    bool Push(LinkStack &S, int e) //入栈
    
    {
        LinkStack p;
        p = new Snode; //现场申请现场用
        p->data = e; //将e附在新结点的data里
        p->next = S;
        S = p;
        return true;
    }
    
    bool Pop(LinkStack &S, int &e) //出栈
    
    {
        LinkStack p;
        if (S == NULL) //栈满
        {
            return false;
        }
        e = S->data; //备份数据
        p = S;
        S = S->next; 
        delete p; //释放空间
        return true;
    }
    

    注:由于入栈时链栈空间可以主动按需申请,因此无需考虑栈满情况

    1.2 栈的引用

    对于常规计算中出现的优先级问题, 用以往我们学过的字符串似乎比较棘手, 所以可以尝试采用栈来处理优先级.
    算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
    例如:

    2+3*(7-4)+8/4
    

    得出

    2 3 7 4 - * + 8 4 / +
    

    1.3 队列

    结构

    操作函数

    结构体定义

    typedef struct QNode{
    	QElemtype *base;
    	int front;
    	int rear;
    }SqQueue; 
    

    队列创建

    void InitQueue(SqQueue *Q)
    {
    	Q->base=(QElemtype*)malloc(sizeof(QElemtype)*QUEUESIZE);
    	assert(Q->base!=NULL);
    	Q->front=Q->rear=0; 
    }
    

    队尾数据入队

    Status EnQueue(SqQueue *Q,QElemtype e)
    {
    	if(Q->rear==QUEUESIZE)
    	{
    		return ERROR;
    	}
    	Q->base[Q->rear]=e;
    	Q->rear++;
    	return OK;
    }
    

    队首数据出队

    Status GetHead(SqQueue *Q,QElemtype *e)
    {
    	if(Q->front==Q->rear)
    	{
    		return ERROR;
    	}
    	*e=Q->base[Q->front];
    	return OK;
    }
    

    环形队列


    拼的不是很圆这是有够抱歉的呢
    具体操作步骤和队列大差不差,就是栈满情况为front=rear%m(m为储存节点个数)

    2. PTA实验作业

    2.1 符号配对

    [https://gitee.com/konjac_wjh/web-2011---blog-code/issues/I3G2DB]

    2.1.1 解题思路

    遍历一遍字符串->抓左括号来入栈->右括号停下查看->匹配就把左出栈->遍历结束在看栈->是为空栈无遗憾 skr~(

    2.1.2 知识点

    创建栈,进出栈

    2.2 银行业务队列简单模拟

    [https://gitee.com/konjac_wjh/web-2011---blog-code/issues/I3G2GN]

    2.2.2 解题思路

    把客人按序号奇数偶数从队尾分装进两个队列, 再用循环按照2A1B输出即可

    2.2.2 知识点

    创建队列,进出队列

    3. 阅读代码

    1. 无法吃午餐的学生数量

    3.1 题目及解题代码

    学校的自助午餐提供圆形和方形的三明治,分别用数字 0 和 1 表示。所有学生站在一个队列里,每个学生要么喜欢圆形的要么喜欢方形的。
    餐厅里三明治的数量与学生的数量相同。所有三明治都放在一个 栈 里,每一轮:
    如果队列最前面的学生 喜欢 栈顶的三明治,那么会 拿走它 并离开队列。
    否则,这名学生会 放弃这个三明治 并回到队列的尾部。
    这个过程会一直持续到队列里所有学生都不喜欢栈顶的三明治为止。
    给你两个整数数组 students 和 sandwiches ,其中 sandwiches[i] 是栈里面第 i​​​​​​ 个三明治的类型(i = 0 是栈的顶部), students[j] 是初始队列里第 j​​​​​​ 名学生对三明治的喜好(j = 0 是队列的最开始位置)。请你返回无法吃午餐的学生数量。
    来源:力扣(LeetCode)
    链接:[https://leetcode-cn.com/problems/number-of-students-unable-to-eat-lunch]

    int countStudents(int* students, int studentsSize, int* sandwiches, int sandwichesSize){
        int arr[2];
        memset(arr, 0, sizeof(arr));
        for (int i=0; i<studentsSize; ++i) {
            ++arr[students[i]];
        }
        for (int i=0; i<sandwichesSize; ++i) {
            if (arr[sandwiches[i]] == 0) break;
            --arr[sandwiches[i]];
        }
        return arr[0] + arr[1];
    }
    

    3.2 该题的设计思路

    若喜欢栈顶的甜点的学生存在,那么不管他们在队伍的哪个位置,必定会遍历到他。否则,一定无法继续拿掉栈顶甜点。

    3.3 难点&优势

    难点

    要将学生依次入队再依次和甜点数组进行比较,如果相等,则此学生出队,三明治数组元素后移一位。如果不相等,则将学生队列中的队头移至队尾,重复比较。用此方法解有一个问题,就是什么时候循环比较的过程可以结束
    由题目可知,当学生队列中的每一个都不喜欢三明治数组里的头元素则循环结束,所以可定义一个用来判断循环能否结束的函数来控制循环次数。最后如果学生队列为空,则返回0,反之,则返回学生队列中的元素个数。

    优势

    对队列的操作大多为基础且易于理解,用一个新循环来判断循环是否应该结束.

  • 相关阅读:
    Implementing Automation Collections
    PSP 2.0降级至1.5详细教程(转)
    Delphi 7 过期的问题
    Delphi读写COM复合文档用户自定义属性参考代码
    十大经典误会
    Office檔案格式(Office文件格式)
    将表格粘贴为Word可识别的格式
    对字符编码与Unicode,ISO 10646,UCS,UTF8,UTF16,GBK,GB2312的理解
    如何识别键盘左右的shift,Ctrl或Alt键
    SRT File Format
  • 原文地址:https://www.cnblogs.com/konjac-wjh/p/14619661.html
Copyright © 2020-2023  润新知