zoukankan      html  css  js  c++  java
  • DS博客作业02--栈和队列

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

    0.PTA得分截图

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

    1.1 栈

    栈的代码定义

    typedef struct {
    	ElemType data[MaxSize];//存放元素
    	int top=-1;//栈顶指针,下标
    }SqStack;//顺序栈的类型
    

    进栈

    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(StackEmpty(s))    //判断是否为空栈
        {
            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)
    {
        if(s->top == -1) //栈为空返回true
        {
            return true;
        }
        return false;
    }
    

    判断栈满

    int FullStack(SqStack s)
    {
    	if (s->top == MaxSize-1)
    		return true;
    	else
    		return false;
    }
    

    销毁栈

    void DestroyStack(SqStack s)
    {
       delete s;
    }
    

    链栈的结构、操作函数

    定义

    typedef struct StackNode
    {
        ElemType data;
        struct StackNode *next;
    }Node,*Stack;
    

    初始化

    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 (StackEmpty(s))		//栈空的情况
    		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(StackEmpty(s))    //判断是否为空栈
        {
            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 栈的应用

    表达式
    中缀表达式:运算符在操作数中间
    后缀表达式:运算符在操作数之后
    中缀表达式转为后缀表达式:
    建立一个栈用于存放运算符,每个运算符号进栈时都要比较一下其和栈顶的的符号优先级大小
    优先级比栈顶运算符高的入栈
    优先级小于等于栈顶运算符时,将栈顶运算符弹出并输出

    1.3 队列

    画一个队列的图形,介绍如下内容。

    定义

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

    基本操作:

    初始化

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

    判断栈空

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

    判断栈满

    bool QueueFULL(SqQueue q)
    {
       return(q->rear==MaxSize-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;
    }
    

    销毁队列

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

    环形队列的结构、操作函数

    结构

    typedef struct
    {ElemType data[MaxSize] ;//存放队中元素
    int front, rear;//队头和队尾指针
    }SqQueue;
    

    初始化

    void InitQueue( SqQueue * &.q)
    { q= (SqQueue * )malloc( sizeof(SqQueue));
    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;
    }
    

    队空

    void QueueEmpty(SqQueue * &q)
    {
    
    return(q-> front==q-> rear);
    }
    

    销毁

    void DestroyQueue(SqQueue * &q)
    {
         free(q);
    }
    

    链队列的结构、操作函数

    结构

    typedef struct qnode
    {ElemType data;//存放元素
    struct qnode * next;//下一个结点指针
    } DatalNode;//链队数据结点的类
    

    初始化

    void InitQueue( LinkQuNde * &.q)
    { q= (LinkQuNde * )malloc( sizeof(LinkQuNde));
    q-> front=q-> rear=NULL;
    }
    

    入队列

    void enQueue(LinkQuNode * &q, ElemType e)
    {
    DataNode*p;
    p= (DataNode * )malloc( sizeof( DataNode)); //创建 新结点
    p-> data=e;
    p-> next= NULL;
    if (q-> rear== NULL)//若链队为空,则新结点既是队首结点又是队尾钻去
        q->front=q-> rear= P;
    else//若链队不空
    { q-> rear-> next= P;//将结点p链到队尾,并将rear 指向它
    q-> rear=p;
    }
    }
    

    出队列

    bool deQueue(LinkQuNode . &q. ElemType &e)
    {
    DataNode *t:
    if(q-> rear== NULL)//原来队列为空
       return false;
    t=q -> front;//t指向首结点
    if (q-> front==q- > rear)
         q-> front=q-> rear= NULL;
    else
       q> front=q-> front-> next;
    e=t-> data;
    free(t);
    return true;
    

    队空

    bool QueueEmpty(LinkQueue * &q)
    {
    
    return(q-> rear==NULL);
    }
    

    销毁队

    void DestroyQueue(LinkQuNode*&q)
    {DataNode * pre=q > front, * p;//pre指向队首结点
    if (pre!=NULL)
    {
    p=pre- > next;//p指向结点pre的后继结点
    while (p!= NULL)//p不空循环
    {free(pre) ;//释放pre结点
    pre=p;P=P- > next;//pre、p同步后移
    }
    free(pre);//释放最后一个数据结点
    }
    free(q);//释放链队结点
    

    队列应用

    6-4 另类循环队列

    只设队列头指针Front,不设尾指针Rear,而是另设Count记录队列中元素个数。编写算法实现队列的入队和出队操作。

    ElementType DeleteQ(Queue Q)
    {
        if (Q->Count == 0)
        {
            printf("Queue Empty
    ");
            return ERROR;
        }
        Q->Count--;
        
        ElementType X;
        X= Q->Data[Q->Front];
        Q->Front = (Q->Front + 1) % Q->MaxSize;
        return X;
    }
    bool AddQ(Queue Q, ElementType X)
    {
        if (Q->Count == Q->MaxSize)
        {
            printf("Queue Full
    ");
            return false;
        }
        
        Q->Data[(Q->Front + Q->Count) % Q->MaxSize] = X;
        Q->Count++;
        return true;
    }
    

    2.PTA实验作业(4分)

    此处请放置下面2题代码所在码云地址(markdown插入代码所在的链接)。如何上传VS代码到码云

    2.1 符号配对

    #include <iostream>
    #include <stack>
    #include <string>
    using namespace std;
    int main()
    {
    	stack <char>str;
    	int i = 0, k = 0, count = 0;
    	char sum[100];
    	char select[100];
    	while (sum[k] = getchar())
    	{
    		if (sum[k] == '(' || sum[k] == '{' || sum[k] == '[' || sum[k] == ')' || sum[k] == ']' || sum[k] == '}')
    		{
    			select[i++] = sum[k];
    			count++;
    		}
    		else
    		{
    			if (sum[k] == '/')
    			{
    				sum[++k] = getchar();
    				if (sum[k] == '*')
    				{
    					select[i++] = '<';
    					count++;
    				}
    			}
    			else if (sum[k] == '*')
    			{
    				sum[++k] = getchar();
    				if (sum[k] == '/')
    				{
    					select[i++] = '>';
    					count++;
    				}
    			}
    		}
    		if (sum[k] == '.')
    		{
    			sum[++k] = getchar();
    			if (sum[k] == '
    ')
    				break;
    		}
    		k++;
    	}
    	for (i = 0; i < count; i++)
    	{
    		if (select[i] == '(' || select[i] == '[' || select[i] == '{' || select[i] == '<')
    		{
    			str.push(select[i]);
    		}
    		else
    		{
    			if (select[i] == ')' || select[i] == ']' || select[i] == '}' || select[i] == '>')
    			{
    				if (str.empty())break;
    				if ((select[i] == ')' && str.top() == '(') || (select[i] == ']' && str.top() == '[') || (select[i] == '}' && str.top() == '{') || (select[i] == '>' && str.top() == '<'))
    					str.pop();
    				else
    					break;
    			}
    		}
    	}
    	if (str.empty() && i == count)
    		cout << "YES";
    	else
    	{
    		cout << "NO" << endl;
    		if (str.empty())
    		{
    			if (select[i] == '<')
    				cout << "/*-?";
    			else if (select[i] == '>')
    				cout << "?-*/";
    			else if (select[i] == '(' || select[i] == '[' || select[i] == '{')
    				cout << select[i] << "-?";
    			else
    				cout << "?-" << select[i];
    		}
    		else
    		{
    			if (str.top() == '<')
    				cout << "/*-?";
    			else if (str.top() == '>')
    				cout << "?-*/";
    			else if (str.top() == '(' || str.top() == '[' || str.top() == '{')
    				cout << str.top() << "-?";
    			else
    				cout << "?-" << str.top();
    		}
    	}
    	return 0;
    }
    
    

    2.1.1 解题思路及伪代码

    思路:
    把各种题目要求的符号都存入一个数组中,其中/* ,*/符号的处理是,判断后以‘<’,‘>’的形式存入数组
    再利用for循环遍历数组依次入栈,若能配对则出栈,不能则break
    最后再判断要输出的内容

    stack <char>str
    	int i = 0, k = 0, count = 0
    	char sum[100]
    	char select[100]
    	while (sum[k] = getchar())
    	
    		if sum[k] == '(' '{'  '['  ')'  ']' '}'
    			select[i++] = sum[k]
    			count++
    		end if
    		else
    			if sum[k] == '/'
    				sum[++k] = getchar()
    				if sum[k] == '*'
    					select[i++] = '<'
    					count++
    				end if
    			end if
    			else if sum[k] == '*'
    				sum[++k] = getchar()
    				if (sum[k] == '/')
    					select[i++] = '>'
    					count++
    				end if
    			end if
    		if sum[k] == '.'
    			sum[++k] = getchar()
    			if sum[k] == '
    '
    				break;
    		end if
    		k++
    	end while
    	for i=0 to count
    		if select[i] 都是左符号
    			入栈
    		end if
    		else
    			if 都是右符号
    				if 栈空 break
    				if 各符号配对
    					出栈
    				else
    					break
    			end if
    		
    	end for
    if栈空且i=len
      输出yes
    else if栈空
      输出no
    else
      输出栈顶和no
    	return 0;
    

    2.1.2 总结解题所用的知识点

    读取字符,读取/**/
    出栈,入栈 :左符号入栈,右符号配对时出栈,判断出栈或入栈或break

    2.2 银行业务队列简单模拟

    #include "stdio.h"
    #include "iostream"
    using namespace std;
    #define MaxSize 1000  
    typedef struct
    {
        int data[MaxSize];
        int front, rear;
    } SqQueue;
    void InitQueue(SqQueue*& q);
    int main()
    {
        int num[MaxSize];
        int n;
        int i;
        int e;
        int count=0;
        SqQueue* A, * B;
        cin >> n;
        for (i = 0; i < n; i++)
        {
            cin >> num[i];
        }
        InitQueue(A);
        InitQueue(B);
        for (i = 0; i < n; i++)
        {
            if (num[i] % 2 == 1)
            {
                A->rear = (A->rear + 1) % MaxSize;
                A->data[A->rear] = num[i];
            }
            else
            {
                B->rear = (B->rear + 1) % MaxSize;
                B->data[B->rear] = num[i];
            }
        }
        while (A->front != A->rear || B->front != B->rear)
        {
            for (i = 1; i <= 2; i++)
            {
                if (A->front != A->rear)
                {
                    A->front = (A->front + 1) % MaxSize;
                    e = A->data[A->front];
                    count++;
                    if (count < n)
                    {
                        cout << e<<' ';
                    }
                    else
                    {
                        cout << e;
                    }
                }
            }
            if (B->front != B->rear)
            {
                B->front = (B->front + 1) % MaxSize;
                e = B->data[B->front];
                count++;
                if (count < n)
                {
                    cout << e << ' ';
                }
                else
                {
                    cout << e;
                }
            }
        }
        return 0;
    }
    void InitQueue(SqQueue*& q)
    {
        q = (SqQueue*)malloc(sizeof(SqQueue));
        q->front = q->rear = 0;
    }
    

    2.2.1 解题思路及伪代码

    思路:
    先把编号都存入一个数组中,再利用for循环,把奇数的编号压入A栈,偶数的编号压入B栈,再利用while循环,先进行2次A栈的出队,再进行一次B栈的出队,直到A、B栈都空

    int num[MaxSize]
        int n
        int i
        int e
        int count=0
        SqQueue* A, * B
        cin >> n
        for i=0 to n
            cin >> num[i]
        end for
        InitQueue(A)
        InitQueue(B)
        for i=0 to n
            if (num[i] % 2 == 1)
            then
                A->rear = (A->rear + 1) % MaxSize
                A->data[A->rear] = num[i]
            end if
            else
                B->rear = (B->rear + 1) % MaxSize
                B->data[B->rear] = num[i]
        end for
        while (A->front != A->rear || B->front != B->rear)
            for i=1 to 2
                if (A->front != A->rear)
                then
                    A->front = (A->front + 1) % MaxSize
                    e = A->data[A->front]
                    count++
                    if (count < n)
                    then
                        cout << e<<' '
                    end if
                    else
                        cout << e
                end if
            end for
            if B->front != B->rear
                B->front = (B->front + 1) % MaxSize
                e = B->data[B->front]
                count++
                if count < n
                then
                    cout << e << ' '
                else
                    cout << e
                end if
            end if
        end while
        return 0
    

    2.2.2 总结解题所用的知识点

    队列的出队和入队
    输出顺序的判断

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

    3.1 题目及解题代码

    考研题

    题目:一个正读和反读都相同的字符序列称为“回文”。例如“abcba”和“1221”是回文,而“abcde”不是回文。试写一个算法,要求利用栈的基本运算识别一个以@为结束符的字符序列是否是回文。

    Status HuiWen(String str)
    { 
    InitStack(&s1);//构造两个空栈  
    InitStack(&s2);  
    i=0;  
    while(str[i++]!='@')   
    Push(&s1,ch);//将字符压入栈s1  
    length=StackLength(s1);//length表示字符个数   
    for(i=0;i<length/2;i++)   
    Push(&s2,Pop(&s1,&e);//将s1中一半的字符逐个压入s2中    
    if(length%2!=0)  //如果栈中元素为奇数个,需要去除s1的栈顶元素,也就是字符序列中间的一个字符   
    Pop(&s1,&e);   
    for(i=0;i<length/2;i++)   
    if(Pop(&s1,&e1)!=Pop(&s2,&e2))//e1和e2不等    
    return false;  //有一个不相等就不是回文,直接结束程序  
    printf(yes);//运行到此步说明两栈字符相等   
    DestroyStack(s1);  //销毁  
    DestroyStack(s2); 
    }//end 
    
    

    3.2 该题的设计思路及伪代码。

    思路:将字符序列顺序压入栈1中,然后将栈1中的一半的字符(这里取商的下界,也就是说如果长度为5,一半表示2,长度为7,一半表示3)逐个压入栈2中,如果两个栈相等,那么是回文,否则不是

    InitStack(&s1)构造两个空栈  
    InitStack(&s2)  
    i=0
    while str[i++]!='@'  
      Push(&s1,ch) 将字符压入栈s1  
    end while
    length=StackLength(s1)length表示字符个数   
    for i=0 to length/2
      Push(&s2,Pop(&s1,&e)  将s1中一半的字符逐个压入s2中    
    end for
    if length%2!=0 如果栈中元素为奇数个,需要去除s1的栈顶元素,也就是字符序列中间的一个字符   
      Pop(&s1,&e) 
    end if
    for i=0 to length/2
      if Pop(&s1,&e1)!=Pop(&s2,&e2) e1和e2不等    
        return false 有一个不相等就不是回文,直接结束程序  
      end if
    end for
    printf(yes)运行到此步说明两栈字符相等   
    DestroyStack(s1)  //销毁  
    DestroyStack(s2) 
    }//end 
    

    时间复杂度:O(n)
    空间复杂度:O(n)

    3.3 分析该题目解题优势及难点。

    考察学生是否熟练栈的应用
    需要考虑字符的个数,若是偶数可直接将一半的字符逐个压入栈中,若是奇数则需要去除栈顶元素

  • 相关阅读:
    LG P4284 [SHOI2014]概率充电器
    LG P2592 [ZJOI2008]生日聚会
    LG P4953 [USACO02FEB]Cow Cycling
    LG P2389 电脑班的裁员
    LG P2344 [USACO11FEB]Generic Cow Protests G
    前端简历
    前端面试题目
    大前端的技术栈
    前端 -为什么要清楚浮动?
    Redis的功能实现
  • 原文地址:https://www.cnblogs.com/jingzheng001/p/14619800.html
Copyright © 2011-2022 走看看