第三章数据结构小结

第三章主要学了栈与队列,其定义,实现,操作。还有可怕的递归算法,以前感觉没什么,现在发现挺有用的,可以不用很复杂的代码解决挺复杂的问题(虽然时间效率有点低,会出现重复的子问题)。

栈可以看成一个容器,先进后出。队列则可以看成一个管道,先进先出。实质大概都是顺序表与链表。在操作顺序栈和顺序队列时要判断其满或空。

     另外看到了一个循环队列:通过取模使得头指针和尾指针相接,非常巧妙。取模在c++中是一个很重要的思想,很多巧妙的方法都由其而来。

     接下来是作业:括号匹配一开始自己打的时候漏洞频出,毕竟书上的和实际跑起来的代码还是有很大的区别。后来通过老师的讲解慢慢实现了出来。主要1.cin.getline的读取方式2.通过设立一个Flag将多个出口统一起来3.回车在这之中会自对转换为\0。

1.给定一串字符,不超过100个字符,可能包括括号、数字、字母、标点符号、空格,编程检查这一串字符中的( ) ,[ ],{ }是否匹配。

输入格式:

输入在一行中给出一行字符串,不超过100个字符,可能包括括号、数字、字母、标点符号、空格。

输出格式:

如果括号配对,输出yes,否则输出no。


#include<iostream> #include<string.h> using namespace std; #define Max_size 150 //最大容量 typedef char data; typedef struct{ data SElemType[Max_size]; int top; }stack; //定义栈 void initial(stack &st) { st.top = 0; } //初始化栈 void push(stack &st, data x) { st.SElemType[st.top] = x; st.top++; } //入栈 char pop(stack &st){ st.top--; return st.SElemType[st.top]; } //出栈 int main(){ stack s; initial(s); string str; getline(cin, str); char ch[150]; strcpy(ch,str.c_str()); int flag=1; int i; for(i=0; ch[i]!='\0'; i++){ //元素若为左则入栈 if((ch[i] == '{' )|| (ch[i] =='[') || (ch[i] =='(')){ push(s, ch[i]); }//元素若为右则出栈 赋值给a else if((ch[i] == '}') || (ch[i] ==']') || (ch[i] ==')')){ char a; a = pop(s); //若a与ch[i]匹配,下一个字符扫描 if((a == '{' && ch[i] == '}') || (a == '(' && ch[i] == ')') || (a == '[' && ch[i] == ']')){ continue; }else flag = 0; } } if(s.top!=0) flag=0; //判断无右符号匹配的情况 if(flag == 0){ cout<<"no"; }else cout<<"yes"; return 0; }

对栈的操作和使用还是不那么熟练,还是要好好练习。

第二个还是比较简单且易实现的,不过感觉自己的代码可能复杂了一点,很多地方都可以继续优化。

2.设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。

输入格式:

输入为一行正整数,其中第1个数字N(≤1000)为顾客总数,后面跟着N位顾客的编号。编号为奇数的顾客需要到A窗口办理业务,为偶数的顾客则去B窗口。数字间以空格分隔。

输出格式:

按业务处理完成的顺序输出顾客的编号。数字间以空格分隔,但最后一个编号后不能有多余的空格。

#include <iostream>
using namespace std;
#define MaxQsize 1001
#define OK 1
#define ERROR -1
typedef int QElemType;
typedef int status;

typedef struct{
    QElemType *base;  //基地址
    int front;  //头指针
    int rear;  //尾指针 
}sqQueue;

status InitQueue(sqQueue &Q){
    Q.base=new QElemType[MaxQsize];  //分配数组空间
    Q.front=Q.rear=0;
    return OK;  //队列为空
}  //构造队列 

status EnQueue(sqQueue &Q,QElemType e){
    if((Q.rear+1)%MaxQsize==Q.front)  return ERROR;    
    Q.base[Q.rear]=e;
    Q.rear=(Q.rear+1)%MaxQsize;
    return OK;
}  //入队 

status DeQueue(sqQueue &Q,QElemType &e){
    if(Q.front==Q.rear)  return ERROR;
    e=Q.base[Q.front];
    Q.front=(Q.front+1)%MaxQsize;
    return OK;
}  //出队 

int GetHead(sqQueue Q){
    if(Q.front!=Q.rear)
    return Q.base[Q.front];
}  //取队头元素 

bool EmptyQueue(sqQueue Q){
    if(Q.rear+1%MaxQsize==Q.front)  return 1;
    else return 0;
}

void Push(int *arr,int n)
{
    cout<<arr[0];
    for(int i=1;i<n;i++)
        cout<<" "<<arr[i];
}

int main(){
    sqQueue Queue1,Queue2;
    InitQueue(Queue1);
    InitQueue(Queue2);
    int num,a,tmp,i=0;
    cin>>num;
    int result[num];  //总数字 
    for(int i=0;i<num;i++){
        cin>>a;
        if(a%2!=0){
            EnQueue(Queue1,a);
        }  //奇数存入队列1 
        else if(a%2==0) EnQueue(Queue2,a);  //偶数存入队列2 
    }
while((Queue1.front!=Queue1.rear)&&(Queue2.front!=Queue2.rear))
    {
        DeQueue(Queue1,tmp);
        result[i++]=tmp;
        DeQueue(Queue1,tmp);
        result[i++]=tmp;
        DeQueue(Queue2,tmp);
        result[i++]=tmp;
    }
    while(Queue1.front!=Queue1.rear)
    {
        DeQueue(Queue1,tmp);
        result[i++]=tmp;
    }
    while(Queue2.front!=Queue2.rear)
    {
        DeQueue(Queue2,tmp);
        result[i++]=tmp;
    }
    Push(result,num);
    return 0;
}

实质就是把奇偶分到两个队列中,然后按照奇数输出;两个偶数输出一个的方式输出,最后一个队列空了之后再把剩下的全部输出。

值得一提的是以前一直都感觉诸如typedef int status这样的东西都是多此一举,结果当找Bug找到神经迷糊的时候怀疑到了这上面来,上网一搜才发现还是增强程序的可读性,让别人让自己都好看懂你这个函数是干什么的。

另外自学了一下sql中的queue,以后就不用这么麻烦啦,这是一篇参考博客:https://blog.csdn.net/cindywry/article/details/51919282。

最近事情有点多,可预见的以后事情会更多。但课内的学习不能落下。希望第四章能把一些东西琢磨透,把思维给提升上来。

posted @ 2019-03-31 20:08  我又不乱来aa  阅读(148)  评论(2编辑  收藏  举报