DS博客作业02--栈与队列

0.PTA得分截图

1.本周学习总结

1.1 栈的总结

1.1.1 栈的结构体

顺式结构:
typedef struct stack{
     int data[MaxSize];
     int top;//记录栈顶位置
}Stack,*SqStack;
链式结构:
typedef struct lstack{
      int data:
      struct lstack *next;
}Lstack,*Slstack;

1.1.2 初始化栈

void InitiateStack(SqStack &sta)
{
    sta=new Stack;
    sta->top=-;
}

1.1.3 入栈

void Push(SqStack &sta,int e)
{
     if(sta->top+1==MaxSize)//检查栈是否已满,非常重要!!!
     {
           return;
     }
     sta->top++;
     sta->data[sta->top]=e;
}

1.1.4 出栈

void Pop(SqStack &sta)//单纯出栈,不保留栈顶元素
{
   if(sta->top==-1)//检查栈是否已空,非常重要!!!
       return
   sta->top--;
}

1.1.5 返回栈顶元素

void GetTop(SqStack sta,int &e)
{
    if(sta->top==-1)
       return;
    e=sta->data[sta->top];
}

1.1.6 销毁栈

void DelStack(SqStack &sta)
{
     delete sta;
}

1.1.7 拓展--共享栈


特殊处:

  1. 与普通栈相比,共享栈的结构体定义中多一个以MaxSize为起始位置的‘top’,在判断栈满时条件‘top1+1==top2’;
  2. 共享栈的使用不多,看看就好......

1.1.8 栈的应用

栈的特点是数据先进先出,时进时出,生活中满足这一条件的有:网页的浏览、递归的运用等等
典型应用:符号配对
伪代码

运用map容器将相应符号配对
输入字符串str并获取其长度length
for 遍历字符串
    if str[i]为左括号
        入栈
    else if str[i]为右括号
             取栈顶元素
            if mp[str[i]]==栈顶元素
                栈顶元素出栈
            else 
                return false

1.2 队列的总结

1.2.1 队列结构体

顺序队列:
typedef struct queue{
      int data[MaxSize];
      int front;
      int rear;
}Queue,*Squeue;
链式结构:
typedef struct queue {
	int num;
	struct queue *next;
}Queue,*Squeue;

typedef struct loc {
	Squeue front;
	Squeue rear;
}Qlink;

1.2.2 建立队列

void initiate(Squeue &q)
{
    q=new Queue;
    q->front=q->rear=-1;
}

1.2.3 入队列

void EnQueue(Squeue &q,int e)
{
    if(q->rear+1==MAxSize) return false;
    q->rear=q->rear+1;
    q->data[q->rear]=e;
}

1.2.4 出队列

void DeQueue(Squeue &q,int e)
{
    if(q->front==q->rear)  retuen;
    q->front=q->front+1;
    e=q->data[q->front];
}

1.2.5 销毁队列

void destroy(Squeue &q)
{
    delete q;
}

1.2.6 判断队列是否为空

bool IsEmpty(Squeue q)
{
    return(q->front==q->rear);
}

1.2.7 拓展--循环队列

  1. 循环队列很好的利用了空间,避免浪费
  2. 判断条件上有差别:rear=(rear+1)%Max,front=(front+1)%Max

1.2.谈谈你对栈和队列的认识及学习体会

  1. 对栈和队列的认识:首先栈和队列脱胎于线性表,前者先进后出,时进时出;后者先进先出,根据这样的数据特点,我们可以自由选择适合的数据结构;
  2. 学习体会:与前几周关于线性表的学习相比,栈和队列让我对数据结构的重要性的认识进一步加深了,尤其是关于银行的三个题目让我体会到合理运用数据对解决问题太重要了,以前知道‘编程=数据结构+算法’,现在真正体会到了。此外,学的过程确实有些吃力,迷宫题目听得云里雾里,pta的题目有时候一个就是几小时,只能说任重道远。

2.PTA实验作业

2.1.题目1:表达式转换

2.1.1代码截图

2.1.2本题PTA提交列表说明

说明:本题其实讲过,思路上没问题,问题是map容器的使用出了问题,两个错误都是因为map容器的格式错误

2.2 题目2:银行业务队列简单模拟

2.2.1代码截图

!

2.2.2本题PTA提交列表说明


Q:错误在输出情况分类中s1或s2为空后没有空格,造成部分答案出错
A:在第一次循环中对s2再次讨论,确定其是否只含一位数。

3.阅读代码

3.1 题目及解题代码

题目:

代码:

public class SortedStack {
    Stack<int> stack = new Stack<int>();
    Stack<int> temp = new Stack<int>();

    public SortedStack()
    {
    }

    public void Push(int val)
    {
        /* 使用两个栈,stack 存储较大的值,temp用来临时存放较小的值
           调整两个栈,使临时栈的值小于插入值,主栈的值大于插入值,这样插入值才可以插入后依然有序
         */
        while (true)
        {
            var max = stack.Count == 0 ? int.MaxValue : stack.Peek();
            var min = temp.Count == 0 ? int.MinValue : temp.Peek();

            if (val > max)
            {
                temp.Push(stack.Pop());
            }
            else if (val < min)
            {
                stack.Push(temp.Pop());
            }
            else
            {
                // 此时调整好了
                break;
            }
        }

        // 往栈写入数据
        stack.Push(val);
    }

    public void Pop()
    {
        // 将临时栈内的数据返回已有栈
        while (temp.Count > 0)
        {
            stack.Push(temp.Pop());
        }

        if (stack.Count == 0)
        {
            return;
        }

        stack.Pop();
    }

    public int Peek()
    {
        // 将临时栈内的数据返回已有栈
        while (temp.Count > 0)
        {
            stack.Push(temp.Pop());
        }

        if (stack.Count == 0)
        {
            return -1;
        }

        return stack.Peek();
    }

    public bool IsEmpty()
    {
        return stack.Count == 0 && temp.Count == 0;
    }
}

3.1.1 该题的设计思路

  1. 借用辅助栈temp来实现栈s的排序

  2. 针对push操作,如果栈s不为空“!s.empty()”并且栈顶元素小于val “s.top()<val”,则将栈顶元素压入栈temp,并将s栈顶元素弹出,直到不满足两个要求为止

  3. 若栈s为空,或者“s.top()>=val”则将val压入栈s中;最后将栈temp的元素一次压入栈s中。

3.1.2 该题的伪代码

建立temp,stack两个栈
void push(int val)
{
    遍历数据,大数入stack,小数入temp
    stack.Push(val)
}

void Pop()
{
    将临时栈内的数据返回stack
}

int Peek()
{
    将临时栈内的数据返回temp
    return stack.Peek()
}

3.1.3 运行结果

3.1.4分析该题目解题优势及难点.

一般根据题干要求,只允许使用辅助栈,很容易想到,每次push前,将栈中元素比当前小的push到辅助栈中,完成后再push回来;每次pop只需将当前栈顶元素pop出来即可。但实际上,我们只需要移动2i次:先把i个元素移到辅助栈,再把n个元素放入栈,最后将辅助栈中元素移回来即可,此为惰性更新(虽然还不是很懂),极大的优化了代码。

3.2 题目及解题代码

题目:

代码:

3.2.2 运行结果

3.2.3分析该题目解题优势及难点

使用两个栈,一个存储顺序的数据,另一个用来反转数据,push就是添加尾节点,pop就是移除首结点并返回节点的内容,peek就是取首节点值但不移除首节点。

猜你喜欢

转载自www.cnblogs.com/my-sky-2019/p/12548430.html