第03次作业-栈和队列

1.学习总结

2.1 

7-3 表达式转换(25 分)

2.2 设计思路(伪代码或流程图)

int main()
{
    定义字符串a保存输入
    定义栈s1
    读入字符串a
    定义计数用变量fu,判断一次循环结束后要不要加空格 
    for(i=0;i!=size(a);i++)
    {
        if a[i]是数字或小数点
        直接输出
        end if 
        else if 当a[i]是减号或加号,判断栈是否为空,或上一个字符是否是左括号
        是则直接输出,且fu++
        end if
        else if 判断是否为括号
        左括号直接入栈 ,遇见右括号则输出左括号之后所有的元素
        end if
        else if 判断是否是正常符号
        如果是,输出直至栈内的优先级不高于自己
        end if
        if 是符号且fu==0
        输出空格 
    } 
    输出数据,不表 
}

2.3 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)

2.4 PTA提交列表说明。

一开始打完代码爆出了多种错误,甚至连一个数字的测试点也错了。详细阅读后题目发现了问题所在,补上了小数点和正负的情况。最后发现还有括号嵌套,换了遇到括号算法。

7-4(选做) 列车调度(25 分)

2.2 设计思路(伪代码或流程图)

定义数组cuntt模拟车道 
int main()
{
    定义队列q1以操作
    定义n保存列车数量,m保存列车车号
    定义t保存列车车道数量
    for(int i=0;i!=n;i++)
    {
        读入m,将m入队 
    } 
    while 队列不为空
    {
        定义变量p保存二分查找的结果
        if p不为0
        将队头出队,进入countt[p]中
        end if
        else 
        在countt中建立新车道,保存队头,t++
        释放队头
        end if 
    } 
    输出t 
}
二分查找,不是此题重点
int erfen(int x,int t)
{
    定义high=t,low=0
    while low<high 
    定义mid=(high+low)/2
    if x>countt[mid] 
    low++或hig-- 
    end if
    end while
    
    return low 
} 

2.3 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)

2.4 PTA提交列表说明。

这一题做起来非常非常痛苦,不是因为题目难度的问题,而是我完全曲解了题目的意思。

在没有梦见一个叫Wikipedia的老头前,我一直以为一条车道只能有一辆火车,所以怎么改simple的答案都是6.

知道这个以后,又因为时间复杂度是n²,只能用二分查找降低时间复杂度。

7-5(选做) 堆栈模拟队列(25 分)

2.2 设计思路(伪代码或流程图)

int main()
{
    定义n,m分别保存两个栈的大小,并定义并读入s1,s2两个栈
    定义变量maxx,minn,其中maxx用来保存m和n里较小的那个,作为满栈标记 
    do
    {
        if ch==A
        读入一个数,定义变量shu保存该数 
            if s1满且s2不为空
                输出错误,end if
            else if s1不满
                shu入s1栈 end if 
            else 
            {
                for(int i=0;i<maxx;i++)
                {
                    把s1中的元素全部压入s2中 
                }
                shu入s1栈 
            } 
        end if
        
        else if ch==D
            if s1不为空
            {
                if s2为空
                {
                    while(!s1.empty())
                    {
                        把s1中的元素全部压入s2中 
                    }
                    输出并释放s2的栈顶元素 
                } 
                else
                     输出并释放s2的栈顶元素 
            } 
            else
                输出空栈错误
            end if
        end if
        读入下一个字母 
    } 
    while(ch!='T')
    end while 
}

 

2.3 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)

2.4 PTA提交列表说明。

我已经搞不清楚这是队列题还是栈题了,救命我要用数组……

一开始我对这题有些误解,以为是用两个栈模拟出来一个长度等于s1+s2的队列,结果错的一塌糊涂。经过广哥点播后恍然大悟,从队列的定义入手,成功解决了这题。

3.截图本周题目集的PTA最后排名

本次2个题目集总分:125+215=340分
必做题共:205分

3.1 栈PTA排名

3.2 队列PTA排名

 

3.3 我的总分:

155+125==280

 

4. 阅读代码

https://gitee.com/AllElnWen/data_structure_linear_table_02_experimental_report/blob/master/%E9%93%BE%E8%A1%A87-1.cpp

 

#include<stdio.h>  
#include<stdlib.h>  
  
typedef struct Node* List;  
struct Node{  
    int data;  
    struct Node *Next;  
};  
List CreatList(); 
void print(List L);  
void read(List L);  
void combine(List L1,List L2,List L3);  
int main()  
{  
    List L1,L2,L3;  
    L1=CreatList();  
    L2=CreatList();  
    L3=CreatList();  
    read(L1);  
    read(L2);  
    combine(L1,L2,L3);  
    print(L3);  
    return 0;  
}  
List CreatList() 
{  
    List L;
    L=(List)malloc(sizeof(struct Node));  
    if(!L)
    return NULL;  
    L->Next=NULL;  
    return L;  
}  
void print(List L)  
{  
    L=L->Next;  
    if(L==NULL)  
    {  
        printf("NULL");  
        return;  
    }  
    while(L)  
    {  
        if(L->Next==NULL)  
            printf("%d",L->data);  
        else printf("%d ",L->data);  
        L=L->Next;  
    }  
          
}  
void read(List L)  
{  
    List s;  
    int data;  
    scanf("%d",&data);  
    while(data>0)  
    {  
        s=(List)malloc(sizeof(struct Node));  
        if(!s) return;  
        s->data=data;  
        s->Next=NULL;  
        L->Next=s;  
        L=s;  
        scanf("%d",&data);  
    }  
    return;  
}  
void combine(List L1,List L2,List L3)  
{  
    L1=L1->Next;  
    L2=L2->Next;  
    while(L1!=NULL&&L2!=NULL)  
    {  
        if(L1->data>L2->data)  
        {  
            L3->Next=L2;  
            L2=L2->Next;  
        }  
        else  
        {  
            L3->Next=L1;  
            L1=L1->Next;  
        }  
        L3=L3->Next;  
    }  
    if(L1==NULL&&L2==NULL) return;  
    if(L1!=NULL)  
        L3->Next=L1;  
    else L3->Next=L2;  
    return;  
}  

很有趣的,这一段代码采用了另一种创建链表的方法:它先用CreatList()函数单单创建了一个表头,之后再调用read()函数真正创造两个链表,在输入的data小于0时结束这个函数。

这样的手法较之普通的创建链表方法,并没有太大优势。

combine()函数不仅仅是将两个链表合并,它更以L->data的大小来对两个链表进行了一次重新排序。即像搭积木一样把两个链表的一个个节点分离,按照data的大小彼此组合,是很精彩的算法。

5. 代码Git提交记录截图

 

posted @ 2018-04-07 20:36  郭胤鑫  阅读(220)  评论(0编辑  收藏  举报