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

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

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

0.PTA得分截图

1.本周学习总结(0-5分)

1.1 栈

栈顶:线性表允许进行插入删除的那一端。
栈底:固定的,不允许进行插入和删除的另一端。
空栈:不含任何元素的空表。
栈的特点:后进先出。

1.1.1顺序栈结构

#define MaxSize <栈存储数据元素的最大值>
typedef struct{
    ElemType data[MaxSize];
    int top;    //栈顶位置
}SqStack;

操作函数

  • 初始化

    void InitStack(SqStack *&s)
    {
        s = new SqStack;//分配一个顺序栈的空间,首地址存放s处
        s->top = -1;    //栈顶指针置为-1
    }
    
  • 进栈

    bool Push(SqStack *&s,ElemType e)
    {
        if(s->top == MaxSize - 1)    //判断是否栈满
        {
            return false;
        }
        s->data[s->top++] = e;    //入栈
        return true;
    }
    
  • 出栈

    bool Pop(SqStack *s,ElemType &e)
    {
        if(s->top == -1)    //判断是否为空栈
        {
            return false;
        }
        e = s->data[s->top--];    //退栈
        return true;
    }          
    
  • 取栈顶元素

    bool GetTop(SqStack *s,ElemType &e)
    {	
       if (s->top==-1)	//判断栈空 
           return false;
        e=s->data[s->top];//栈顶元素赋值为e
        return true;
    }
    
  • 判断栈空

    bool StackEmpty(SqStack *s)
    {
        return(s->top == -1);
    }
    
  • 销毁栈

    void DestroyStack(SqStack *&s)
    {
       delete s;
    }                        
    

1.1.2链栈结构

typedef struct linknode
{
    ElemType data;
    struct linknode *next;
}LiStack;

操作函数

  • 初始化

    bool InitStack(Stack &s)
    {
        s = NULL;
        return true;
    }
    
  • 进栈

    void Push(Stack& s, ElemType e)
    {
    	Stack p;
    	p = new Node;
    	p->data = e;		//新建节点p
    	p->next = s->next;	//插入*p节点作为开始节点
    	s->next = p;
    }
    
  • 出栈

    bool Pop(Stack *&s, ElemType& e)
    {
    	Stack p;
    	if (s->next == NULL)		//栈空的情况
    		return false;
    	p = s->next;			//p指向开始节点,从栈顶开始出栈
    	e = p->data;
    	s->next = p->next;		//删除*p节点
    	delete p;				//释放*p节点
    	return true;
    }         
    
  • 取栈顶元素

    bool GetTop(SqStack &s,ElemType e)
    {
        if(s->next == NULL)    //判断是否为空栈
        {
            return false;
        }
        e = s->data;    //取栈顶
        return true;
    }
    
  • 判断栈空

    bool StackEmpty(Stack *s)
    {
        if(s == NULL)
        {
            return true;
        }
        return false;
    }
    
  • 销毁栈

    void DestroyStack(Stack &s)
    { 
       Stack p;
       while (s!=NULL)
       {   p=s; 	
           s=s->next;
           delete p; 
       }
     }                       
    

1.2 栈的应用

  • InitStack(&S):初始化一个空栈S。
  • StackEmpty(S):判断一个栈是否为空,若栈为空则返回true,否则返回false。
  • Push(&S, x):进栈(栈的插入操作),若栈S未满,则将x加入使之成为新栈顶。
  • Pop(&S, &x):出栈(栈的删除操作),若栈S非空,则弹出栈顶元素,并用x返回。
  • GetTop(S, &x):读栈顶原色,若栈S非空,则用x返回栈顶元素。
  • DestroyStack(&S):栈销毁,并释放S占用的存储空间(“&”表示引用调用)。

1.3 队列

#define MaxSize <队列存储数据元素的最大值>
typedef struct 
{     ElemType data[MaxSize]; 
      int front,rear;      //队首和队尾指针
}SqQueue;

操作函数

  • 初始化

    void InitQueue(SqQueue &q)
    {	q=new Queue;
    	q->front=q->rear=-1;
    }
    
  • 进队

    bool enQueue(SqQueue &q,ElemType e)
    {  
        if (q->rear+1==MaxSize)	   return false;
                                           //队满上溢出
    	q->rear=q->rear+1;
    	q->data[q->rear]=e;
    	return true;
    }
    
  • 出队

    bool deQueue(SqQueue &q,ElemType &e)
    {	
        if (q->front==q->rear)  //队空下溢出
    	 return false;
    	q->front=q->front+1;
    	e=q->data[q->front];
    	return true;
    }          
    
  • 判断队空

    bool QueueEmpty(SqQueue q)
    {
       return(q->front==q->rear);
    }
    
  • 销毁队列

    void DestroyQueue(SqQueue &q)
    {
      delete q;
    }                       
    

1.3.2环形队列

#define MaxSize <队列存储数据元素的最大值>
typedef struct 
{     ElemType data[MaxSize]; 
      int front,rear;      //队首和队尾指针
}SqQueue;

操作函数

  • 初始化

    void InitQueue(SqQueue &q)
    {	
        q=new Queue;
    	q->front=q->rear=0;
    }
    
  • 进队

    bool enQueue(SqQueue &q,ElemType e)
    {	if ((q->rear+1)%MaxSize==q->front)	//队满上溢出
    		return false;
    	q->rear=(q->rear+1)%MaxSize;
    	q->data[q->rear]=e;
    	return true;
    }
    
  • 出队

    bool deQueue(SqQueue &q,ElemType &e)
    {	if (q->front==q->rear)		//队空下溢出
    		return false;
    	q->front=(q->front+1)%MaxSize;
    	e=q->data[q->front];
    	return true;
    }        
    
  • 判断队空

    bool QueueEmpty(SqQueue q)
    {
       return(q->front==q->rear);
    }
    
  • 循环队列长度

    int QueueLength (SqQueue Q)
    {
         return (Q.rear-Q.front+MaxSize)%MaxSize;                   
    }
    

1.3.3链队列

typedef struct LNode{//节点 
	int Data;		//数据 
	struct LNode *Next;//指针 
}Node; 
typedef struct{
	Node *front;	//队头指针 
	Node *rear;		//队尾指针 
}LinkQueue;

操作函数

  • 初始化

    void InitQueue(SqQueue &q)
    {	
        q=new Queue;
    	q->front=q->rear=0;
    }
    
  • 进队

    bool enQueue(SqQueue &q,ElemType e)
    {	if ((q->rear+1)%MaxSize==q->front)	//队满上溢出
    		return false;
    	q->rear=(q->rear+1)%MaxSize;
    	q->data[q->rear]=e;
    	return true;
    }
    
  • 出队

    bool deQueue(SqQueue &q,ElemType &e)
    {	if (q->front==q->rear)		//队空下溢出
    		return false;
    	q->front=(q->front+1)%MaxSize;
    	e=q->data[q->front];
    	return true;
    }        
    
  • 判断队空

    bool QueueEmpty(SqQueue q)
    {
       return(q->front==q->rear);
    }
    

1.3.4队列应用

  • 6-4 另类循环队列
bool AddQ( Queue Q, ElementType X ){
    int rear;
    if(Q->Count == Q->MaxSize)
    {
        printf("Queue Full\n");
        return false;
    }
    rear = (Q->Front + Q->Count) % Q->MaxSize;
    rear = (rear+1)%Q->MaxSize;
    Q->Data[rear] = X;
    Q->Count++;
    return true;
}

ElementType DeleteQ( Queue Q ){
    int x;
    int rear;
    rear = (Q->Front + Q->Count -1) % Q->MaxSize;
    if(Q->Count == 0)
    {
        printf("Queue Empty\n");
        return ERROR;
    }
    Q->Front = (Q->Front + 1) % Q->MaxSize;
    x = Q->Data[Q->Front];
    Q->Count--;
    return x;
}
  • 6-3 jmu-ds-舞伴问题
int QueueLen(SqQueue Q){
    int len;
    len = Q->rear - Q->front;
    return len;
}

int EnQueue(SqQueue &Q, Person e){
    Q->rear++;
    Q->data[Q->rear] = e;
    return true;
}

int QueueEmpty(SqQueue &Q){
    if( Q->front == Q->rear )
        return true;
    else 
        return false;
}

int DeQueue(SqQueue &Q, Person &e){
    if(QueueEmpty(Q))
        return false;
    Q->front++;
    e = Q->data[Q->front];
    return true;
}

void DancePartner(Person dancer[], int num){
    Person e;
    int i;
    for(i = 0; i < num; i++){
        if(dancer[i].sex == 'F')
            EnQueue(Fdancers, dancer[i]);
        else 
            EnQueue(Mdancers, dancer[i]);
    }
    
    if(QueueLen(Fdancers) > QueueLen(Mdancers)){
        while(!QueueEmpty(Mdancers)){
            DeQueue(Fdancers, e);
            cout << e.name << "  ";
            DeQueue(Mdancers, e);
            cout << e.name << endl;
        }
    }
    else{
        while(!QueueEmpty(Fdancers)){
            DeQueue(Fdancers, e);
            cout << e.name << "  ";
            DeQueue(Mdancers, e);
            cout << e.name << endl;
        }
    }
}

2.PTA实验作业(4分)

2.1 符号配对

 #include <iostream>

#include <stack>
using namespace std;
int main()
{
    stack<char> C;
    string ss="",s1;
    while(true)
    {
        getline(cin,s1);
        if(s1==".")
        {
            break;
        }
        else
            for(int i=0; i<s1.length(); i++)
            {
                s1[i];
                if(s1[i]=='{'||s1[i]=='['||s1[i]=='('||s1[i]==']'||s1[i]=='}'||s1[i]==')')
                {
                    ss=ss+s1[i];
                }
                else if(s1[i]=='/'&&s1[i+1]=='*')
                {
                    ss+='<';
                    i++;
                }
                else if(s1[i]=='*'&&s1[i+1]=='/')
                {
                    i++;
                    ss+='>';
                }
            }
    }

    for(int i=0; i<ss.length(); i++)
    {
        if(ss[i]=='('||ss[i]=='['||ss[i]=='{'||ss[i]=='<')
        {
            C.push(ss[i]);
        }
        else if(C.empty())
        {
            if(ss[i]=='>')
            {
                cout<<"NO"<<endl;
                cout<<"?-*/"<<endl;
            }
            else
            {
                cout<<"NO"<<endl;
                cout<<"?-"<<ss[i]<<endl;
            }
            return 0;
        }
        else if(C.top()=='(')
        {
            if(ss[i]==')')
            {
                C.pop();
            }
            else
            {
                cout<<"NO"<<endl;
                cout<<C.top()<<"-?"<<endl;
                return 0;
            }
        }
        else if(C.top()=='[')
        {
            if(ss[i]==']')
            {
                C.pop();
            }
            else
            {
                cout<<"NO"<<endl;
                cout<<C.top()<<"-?"<<endl;
                return 0;
            }
        }
        else if(C.top()=='{')
        {
            if(ss[i]=='}')
            {
                C.pop();
            }
            else
            {
                cout<<"NO"<<endl;
                cout<<C.top()<<"-?"<<endl;
                return 0;
            }
        }
        else if(C.top()=='<')
        {
            if(ss[i]=='>')
            {
                C.pop();
            }
            else
            {
                cout<<"NO"<<endl;
                cout<<"/*-?"<<endl;
                return 0;
            }
        }
    }
    if(!C.empty())
    {
        if(C.top()=='<')
        {
            cout<<"NO"<<endl;
            cout<<"/*-?"<<endl;
        }
        else
        {
            cout<<"NO"<<endl;
            cout<<C.top()<<"-?"<<endl;
        }
    }
    else
    {
        cout<<"YES"<<endl;
    }
    return 0;
}

总结解题所用的知识点

当程序遇到左符号时入栈,遇到右符号出栈一个元素,到最后如果栈为空时,判断匹配成功或者左边符号没有入栈,如果为第二种情况且有右符号缺左符号,如果最后栈不为空则缺右符号。

2.2 银行业务队列简单模拟

 #include <iostream>

#include<algorithm>
#include<queue>
using namespace std;
int main()
{
	queue<int> q;
	int n;
	cin>>n;
	int a[10002];
	int sum=-1;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
		if(a[i]%2==1)
		sum=i;
	}
	int k=0;
	int u=0;
	for(int i=0;i<n;i++)
	{
		if(a[i]%2==1)
		{
			if(u==0)
		{
		cout<<a[i];
		u=1;
	    }
		else
		cout<<" "<<a[i];
		k++;
	    }
	    else if(a[i]%2==0)
	    {
	    	q.push(a[i]);
		}
		if((k==2&&q.empty()==false)||(i>sum&&q.empty()==false))
		{
			if(sum==-1)
			{
			cout<<q.front();
			sum=-2;
		    }
			else
			cout<<" "<<q.front();
			q.pop(); 
			k=0;
		}
	}
	return 0;
}

总结解题所用的知识点

  1. 将a、b两个窗口所接待的用户分别输入两个队列中
  2. 按照a用户两个,b用户一个的顺序输出
  3. 最后输出剩余队列的元素。
  • 注:提交代码的时候一定要修改语言设置,不然会编译错误。。。

3.阅读代码(0--1分)

3.1 题目及解题代码

验证栈序列

class Solution {
public:
          bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
          stack<int >  a;
          int sizePush=pushed.size();
          int sizePop=popped.size();
          int sizePush1=0;
          int sizePop1=0;
          while (sizePush1<sizePush&&sizePop1<sizePop){
          a.push(pushed[sizePush1]);
          while(!a.empty()&&a.top()==popped[sizePop1]){//查看是否可以出栈
                 a.pop();
                 sizePop1++;
                } 
          sizePush1++;
          } 
          return a.empty();
       }
 };

3.2 该题的设计思路

设计思路:利用了一个栈,虚拟了出栈和入栈的过程,如果要入的元素和出栈的元素相等时,相当于是刚入就出,我们可以不进行入栈出栈,再判断临时栈中的元素是不是下一个要出栈的元素,如果是则进行出栈,再接着判断下一个栈中的元素是不是刚刚判断过得要出栈的元素的下一个元素,如果不是请继续入栈。以次类推,如果最后临时栈中还有

posted on 2021-04-05 22:03  姚庆荣  阅读(76)  评论(0编辑  收藏  举报