zoukankan      html  css  js  c++  java
  • 栈和队列

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

    0.PTA得分截图

    1.本章学习总结

    1.1栈

    顺序栈

    栈的顺序存储结构

    typedef struct{
      ElemType data[Maxsize];
      int top;//栈顶指针
    }Stack;
    typedef Stack *SqStack;
    

    初始化栈

    s=new Stack;
    s->top=-1;
    

    进栈

    if(s->top==MaxSize-1)//顺序栈必须考虑栈满
     return false;
    s->top++;//栈顶指针上移
    s->data[s->top]=e;
    return true;
    

    出栈

    if(s->top==-1)//考虑栈为空
     return false;
    e=s->data[s->top];
    s->top--;
    return true;
    

    取栈顶元素

    if(s->top==-1)//栈为空
     return false;
    e=s->data[s->top];
    return true;
    

    共享栈

    需要用到两个相同类型的栈,可以用一个数组data[0...MaxSize-1]来实现这两个栈

    typedef struct{
     ElemType data[MaxSize];
     int top1,top2;
    }DStack;
    

    栈1空:top1=-1
    栈2空:top2=MaxSize
    栈满:top1+1=top2

    链栈

    链栈中数据节点类型定义

    typedef int ElemType;
    typedef struct linknode{
     ElemType data;
     struct linknode *next;
    }LiNode,*LiStack;
    

    初始化栈

    s=new LiNode;
    s->next=NULL;
    

    销毁栈

    LiStack node;
    while(s!=NULL)
    {
     node=s;//保存结点
     s=s->next;//后移
     delete node;
    }
    

    进栈

    LiStack p;
    p=new LiNode;
    p->data=e;
    p->next=s->next;//头插
    s->next=p;
    

    出栈

    LiStack p;
    if(s->next=NULL)//栈空
     return false;
    p=s->next;//p为s后继
    e=p->data;
    s->next=p->next;//改变next关系
    delete p;//该元素被删除
    return true;
    

    取栈顶元素

    if(s->next==NULL)
     return false;
    e=s->next->data;
    return true;
    

    1.2栈的应用

    表达式

    中缀表达式:运算符在操作数中间
    后缀表达式:运算符在操作数之后
    例:62/3-42+=
    6入栈,2入栈,遇到运算符/,6和2出栈,计算6/2得3入栈,3入栈,遇到运算符-,3和3出栈,计算3-3得0入栈,4入栈,2入栈,遇到运算符
    ,4和2出栈,计算4*2得8入栈,遇到运算符+,0和8出栈,计算0+8得8,所以运算结果为8

    规则:遇到操作数入栈,直到遇到运算符把栈顶的两个操作数出栈,再把计算结果入栈

    中缀如何转后缀

    规则:
    1.优先级比栈顶运算符高的入栈
    2.低或相等,一直出栈到栈顶为空或者更高,写入后缀表达式
    例:将a+bc+(de+f)g转为后缀表达式
    +进栈,
    进栈,+优先级低于,所以前面的和+出栈,该+进栈,(进栈,进栈,+优先级低于出栈,该+进栈,遇到),(和+出栈,进栈,结束,和+出栈,所以后缀表达式为abc+def+g+

    1.3队列

    顺序队列

    顺序队类型定义

    typedef struct{
     ElemType data[MaxSize];
     int front,rear;//队头和队尾指针
    }Queue;
    typedef Queue *SqQueue;
    

    初始化队列

    q=new Queue;
    q->front=q->rear=-1;
    

    进队列

    if(q->rear=MaxSize-1)return false;//队满
    q->rear=q->rear+1;//尾指针后移
    q->data[q->rear]=e;
    return true;
    

    出队列

    if(q->front=q->rear)return false;//考虑队空
    q->front=q->front+1;
    e=q->data[q->front];
    return true;
    

    环形队列

    环形队列结构体

    typedef struct{
     ElemType data[MaxSize];
     int front,rear;//队头和队尾指针
    }Queue;
    typedef Queue *SqQueue;
    

    指针循环加一

    rear=(rear+1)%MaxSize;
    front=(front+1)%MaxSize;
    

    初始化

    q=new Queue;
    q->front=q->rear=0
    

    进环形队列

    if((q->rear+1)%maxsize=q->front)return false;
    q->rear=(q->rear+1)%maxsize;
    q->data[q->rear]=e;
    return true;
    

    出环形队列

    if(q->front=q->rear)return false;
    e=q->data[q->front]
    q->front=(q->front+1)%maxsize;
    return true;
    

    链队

    单链表中数据节点类型定义:

    typedef struct qnode{
     ElemType data;
     struct qnode *next;
    }QNode;
    

    链队中头尾指针类型定义:

    typedef struct{
     QNode *front;
     QNode *rear;
    }LinkQueue;
    
    LinkQueue q;
    q.rear;
    q.front;
    q.front->next;
    

    入队

    q.rear->next=node;
    q.rear=node;
    

    出队

    node=q.front->next;
    q.front->next=node->next;
    delete node;
    

    链队初始化

    q.front=q.rear=new QNode;
    if(!q.front)exit(OVERFLOW);
    q.front->next=NULL;
    

    求链队头元素

    if(q.front=q.rear)return ERROR;//队空
    e=q.front->next->data;
    

    链入队

    p=new QNode;
    if(!p)exit(OVERFLOW);
    p->data=e;
    p->next=NULL;
    q.rear->next=p;
    q.rear=p;
    

    出队

    if(q.front=q.rear)return ERROR;
    p=q.front->next;
    e=p->data;
    q.front->next=p->next;
    if(q.rear=p)q.rear=q.front;//最后一个被删,改队尾
    delete p;
    

    队列应用-报数问题

    初始化队列,n个人进队列
    while(队列不空)
     出队一个元素,输出其编号
     若队列不空,再出队一个元素,再将其入队
    
    queue<int>qu;//初始化
    for(i=0;i<n;i++)
    {
      qu.push;//入栈
    }
    while(!qu.empty)
    {
      cout<<qu.front()<<"'";//输出队头
      qu.pop();//出队
      
      if(!qu.empty)//while不为空时,上面出队导致此时可能为空,不能再出队
      {
        front=qu.front();//获得队头元素
        qu.pop();//出栈
        qu.push();//入栈
      }
    }
    

    2.PTA实验作业

    2.1符号配对

    #include<iostream>
    #include <string>
    #include<stack>
    using namespace std;
    bool MatchExp(string exp);
    
    
    int main()
    {
    
    	string exp;//声明一个字符串变量
    	cin >> exp;//输入表达式
    	if (MatchExp(exp))
    		cout << "yes";
    	else
    		cout << "no";
    	return 0;
    }
    
    bool MatchExp(string exp)
    {
    	int i;
    	char top;
    	stack<char>st;//初始化栈
    
    	for (i = 0; i < exp.size(); i++)
    	{
    		if (exp[i] == '(')
    			st.push(exp[i]);//进栈
    		else if (exp[i] == ')')
    		{
    			if (st.empty())//只剩右边符号)
    				return false;
    			top = st.top();//取栈顶元素
    			if (top != '(')
    			{
    			
    			cout << st.top() << "
    ";
    			return false;//配对不成功
    		    }
    			else//配对成功
    				st.pop();//出栈
    		}
    		if (exp[i] == '{')
    			st.push(exp[i]);//进栈
    		else if (exp[i] == '}')
    		{
    			if (st.empty())//只剩右边符号)
    				return false;
    			top = st.top();//取栈顶元素
    			if (top != '{')
    			{
    
    				cout << st.top() << "
    ";
    				return false;//配对不成功
    			}
    			else//配对成功
    				st.pop();//出栈
    		}
    		if (exp[i] == '[')
    			st.push(exp[i]);//进栈
    		else if (exp[i] == ']')
    		{
    			if (st.empty())//只剩右边符号)
    				return false;
    			top = st.top();//取栈顶元素
    			if (top != '[')
    			{
    
    				cout << st.top() << "
    ";
    				return false;//配对不成功
    			}
    			else//配对成功
    				st.pop();//出栈
    		}
    
    	}
    	if (exp[i] == '' && st.empty())//上面循环中匹配成功的没有return,遍历完且栈为空的说明都配对成功了
    		return true;
    	else if (!(st.empty()))//如({
    	{
    		cout << st.top()<<endl;
    		return false;
    	}
    
    
    }
    

    2.1.1

    解题思路:遇到(进栈,遇到)时取栈顶,如果是(则配对成功,否则不成功
    伪代码:

    初始化栈
    for i 0 to exp.size()
     if(是‘(’)
      入栈
     else if(是')')
       if(栈为空)return 
       取栈顶元素
       if(不是‘)’)
        配对不成功
       else
        配对成功;出栈;
      if(是‘{’)
       ......
    if(表达式遍历完且栈为空)
    return true
    else if(栈不为空)
    cout栈顶;
    return false
    

    2.1.2知识点

    1.在头文件中用了#include,可直接用string+变量名来声明一个字符串变量
    2.初始化栈:stack<变量类型>变量名 初始化队列:queue<变量类型>变量名

    2.2银行业务队列简单模拟

    #include<iostream>
    #include<string>
    #include<queue>
    using namespace std;
    int main()
    {
    	int a[1001];
    	queue<int>qa;//存放奇数
    	queue<int>qb;//存放偶数
    	int N;
    	cin >> N;
    	int i;
    	for (i = 0; i < N; i++)//入队
    	{
    		cin >> a[i];
    		if (a[i] % 2 == 0)
    			qb.push(a[i]);
    		else
    			qa.push(a[i]);
    	}
    	int x, y;//存队头
    	if (qa.size() > qb.size() * 2)//最后是以qa的数结尾,qa的最后一个元素后面不能加空格
    	{
    		while (!qa.empty() || !qb.empty())
    		{
    			if (!qa.empty())
    			{
    				x = qa.front();
    				cout << x;
    				qa.pop();
    				if (qa.size() != 0)
    					cout << " ";
    				x = qa.front();//重复两次
    				cout << x;
    				qa.pop();
    				if (qa.size() != 0)
    					cout << " ";
    			}
    			if (!qb.empty())
    			{
    				y = qb.front();
    				cout << y;
    				qb.pop();
    				cout << " ";
    			}
    		}
    	}
    	else//最后是以qb的数结尾,qb的最后一个元素后面不能加空格
    	{
    		while (!qa.empty() || !qb.empty())
    		{
    			if (!qa.empty())
    			{
    				x = qa.front();
    				cout << x;
    				qa.pop();
    
    				cout << " ";
    				x = qa.front();
    				cout << x;
    				qa.pop();
    
    				cout << " ";
    			}
    			if (!qb.empty())
    			{
    				y = qb.front();
    				cout << y;
    				qb.pop();
    				if (qb.size() != 0)
    					cout << " ";
    			}
    		}
    	}
    	return 0;
    }
    

    2.2.1

    解题思路:把数字存放到两个队列中,奇数放入qa队列,偶数放入qb队列,每输出两个qa中的数字,再输出qb中的一个数字
    伪代码:

    定义一个a数组,存放输入的数字
    初始化两个队列
    输入元素个数N
    for i 0 to N
    {
      if 是偶数 则入qb队列
      else 入qa队列
    }
    if(qa长度大于qb长度的两倍)
    {
     while(两队列都不为空)
     {
       if(qa不为空)
       {
         取队头x
         输出x
         出队
         if(长度不为0)则cout“ ”
         再重复一次上述过程
         ....
        }
        if(qb不为空)
        {
           取队头y
         输出y
         出队
         cout" "
         }
       }
    }
    else
    注意最后的空格格式
    return 0;
    }
    

    2.2.2知识点

    要注意最后是以qa还是qb的元素结尾,这关系到结尾不能有空格,要分情况讨论

  • 相关阅读:
    阅读13-17章
    阅读<构建之法>10、11、12章
    作业5.2
    作业5.1
    作业四:构建之法的困惑和思考(5-7)
    做汉堡
    作业三:构建之法的困惑和思考(1-5)
    实验二 合作:王宏财 http://www.cnblogs.com/wanghongcai/
    实验一--四则运算
    数独九宫格
  • 原文地址:https://www.cnblogs.com/wxy1459995649/p/14615129.html
Copyright © 2011-2022 走看看