c++基础数据结构之栈、队列、链表
队列
1 2 3 4 5 6 7
   | queue<int>q  q.pop() q.push() q.front() q.rear() q.size() q.empty()
 
  | 
 
栈
1 2 3 4 5 6
   | stack<int>st st.pop() st.push() st.top() st.size() st.empty()
 
  | 
 
1.单链表(注意结构体写法)
题目描述
实现一个单链表,链表初始为空,支持三种操作: 
(1) 向链表头插入一个数;
(2) 删除第k个插入的数后面的数;
(3) 在第k个插入的数后插入一个数
现在要对该链表进行M次操作,进行完所有操作后,从头到尾输出整个链表。
注意:题目中第k个插入的数并不是指当前链表的第k个数。例如操作过程中一共插入了n个数,则按照插入的时间顺序,这n个数依次为:第1个插入的数,第2个插入的数,…第n个插入的数。 
https://www.ixigua.com/7241418740699824643
输入格式
第一行包含整数M,表示操作次数。 
接下来M行,每行包含一个操作命令,操作命令可能为以下几种: 
(1) “H x”,表示向链表头插入一个数x。 
(2) “D k”,表示删除第k个输入的数后面的数(当k为0时,表示删除头结点)。 
(3) “I k x”,表示在第k个输入的数后面插入一个数x(此操作中k均大于0)。 
输出格式
共一行,将整个链表从头到尾输出。 
数据范围
1≤M≤100000
所有操作保证合法。 
输入样例 复制
1 2 3 4 5 6 7 8 9 10 11
   | 10 H 9 I 1 1 D 1 D 0 H 6 I 3 6 I 4 5 I 4 5 I 3 4 D 6
 
  | 
 
输出样例 复制
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
   | #include<iostream> using namespace std; struct node {      int num;      int time;      node* next;  }; node* head = new node(); void headin(int n,int i){     node* p=new node();     p->num=n;     p->time=i;
           p->next=head->next;     head->next=p; } void de(int t){     node* p, * q;     p=head->next;     if(!t){         head->next=p->next;         delete(p);     }     else{         while(p){             if(p->time==t)break;             p=p->next;         }         q=p->next;         p->next=q->next;         delete(q);     } } void insert(int t,int n,int i){     node* p=head->next;           node* q=new node();     q->num=n;     q->time=i;          while(p){         if(p->time == t)break;         p=p->next;     }          q->next=p->next;     p->next=q; }
  int main(){     head->next=NULL;     int m,i,x,k;     char op;     i=1;     cin>>m;     while(m--){         cin>>op;         if(op=='H'){             cin>>x;             headin(x,i);             i++;         }         if(op=='D'){             cin>>k;             de(k);         }         if(op=='I'){             cin>>k>>x;             insert(k,x,i);             i++;         }                 }     node* p = head->next;     while(p){         cout<< p->num << ' ';         p=p->next;     } }
 
  | 
 
2.简单计算器
题目描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
https://www.ixigua.com/7213692123635024436
输入格式
每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。
100 * 2 + 100 / 2 - 100 * 2 - 4 / 2
输出格式
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
输入样例 复制
输出样例 复制
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
   | #include<iostream> #include<stack> using namespace std; stack<double>d_st; stack<char>op_st;
  int level(char a){     if(a=='+'||a=='-')return 1;     if(a=='*'||a=='/')return 2; } void cal(){     char c=op_st.top();op_st.pop();     double a,b;     a=d_st.top();     d_st.pop();     b=d_st.top();     d_st.pop();     if(c=='+')d_st.push(b+a);     if(c=='-')d_st.push(b-a);     if(c=='*')d_st.push(b*a);     if(c=='/')d_st.push(b/a); } int main(){     string str;     double x;     getline(cin,str);     int len=str.size();     for(int i=0;i<len;i++){         if(str[i]>='0' && str[i]<='9'){             x=str[i]-'0';              while(str[i+1]>='0' && str[i+1]<='9'){                 x=x*10+str[i+1]-'0';                 i++;             }             d_st.push(x);         }         else if(str[i]=='+' || str[i]=='-' || str[i]=='*' || str[i]=='/'){             if(op_st.empty()||level(str[i])>level(op_st.top())){                 op_st.push(str[i]);             }             else if(!op_st.empty() && level(str[i])<=level(op_st.top())){                 while(!op_st.empty() && level(str[i])<=level(op_st.top())){                     cal();                 }                 op_st.push(str[i]);                        }         }     }     while(!op_st.empty()){         cal();     }     printf("%.2lf",d_st.top()); }
 
  | 
 
3.约瑟夫环(队列解法)
题目描述
有n(n<100)个人依次围成一圈,从第1个人开始报数,数到第m个人出列,然后从出列的下一个人开始报数,数到第m个人又出列,…,如此反复到所有的人全部出列为止。设n个人的编号分别为1,2,…,n,打印出列的顺序。
输入格式
n和m。
输入样例
输出样例
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | #include<iostream> #include<queue> using namespace std; int main(){     queue<int>qe;     int n,m;     cin>>n>>m;     for(int i=1;i<=n;i++){         qe.push(i);     }     while(!qe.empty()){         int x;         for(int i=1;i<=m-1;i++){             x=qe.front();             qe.pop();qe.push(x);         }         x=qe.front();qe.pop();         cout<<x<<" ";     } }
 
  | 
 
4.走出迷宫(bfs)
题目描述
当你站在一个迷宫里的时候,往往会被错综复杂的道路弄得失去方向感,如果你能得到迷宫地图,事情就会变得非常简单。
假设你已经得到了一个n*m的迷宫的图纸,请你找出从起点到出口的最短路。
视频讲解:https://www.ixigua.com/7166253132702450212
输入格式
第一行是两个整数n和m(1≤n,m≤100),表示迷宫的行数和列数。
接下来n行,每行一个长为m的字符串,表示整个迷宫的布局。字符‘.’表示空地,‘#’表示墙,‘S’表示起点,‘T’表示出口。
输出格式
输出从起点到出口最少需要走的步数。
输入样例
输出样例
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
   | #include<iostream> #include<queue> using namespace std; char a[105][105]; int vis[105][105]; int n,m; struct node{     int r,c;     int step; };
  int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; void bfs(int sr,int sc,int er,int ec){     queue<node>qe;     node q,t;     q.r=sr,q.c=sc;     q.step=0;     qe.push(q);     vis[q.r][q.c]=1;     while(!qe.empty()){         q=qe.front();         qe.pop();         if(q.r==er && q.c==ec){             cout<<q.step;             break;         }         for(int i=0;i<4;i++){             t.r=q.r+dir[i][0];             t.c=q.c+dir[i][1];             if(a[t.r][t.c]=='.' && vis[t.r][t.c]==0 && t.r>=1&&t.r<=n && t.c>=1&&t.c<=n){                 t.step=q.step+1;                 vis[t.r][t.c]=1;                 qe.push(t);             }         }     } }
  int main(){     int sr,sc,er,ec;     cin>>n>>m;     for(int i=1;i<=n;i++)     for(int j=1;j<=m;j++){         cin>>a[i][j];         if(a[i][j]=='S')sr=i,sc=j;         if(a[i][j]=='T')er=i,ec=j,a[i][j]='.';     }     bfs(sr,sc,er,ec); }
 
  | 
 
5.出入栈判断
题目描述
现有 a∼z 26 个小球模拟出入栈操作,小球按照 a∼z 的顺序压入栈,在栈顶的元素可以随时被取出,在游戏开始前给出任意 26 个字母的一些排列,问是否能够由出栈顺序得到这个排列。
输入格式
输入第一行表示一个整数n, n<=100
接下来输入n行,每行表示一个a~z的排列。
输出格式
每组数据输出一行结果,如果能够由出栈顺序得到给定排列,则输出 yes,否则输出 no。
输入样例 复制
1 2 3
   | 2 abcdefghijklmnopqrstuvwxyz zabcdefghijklmnopqrstuvwxy
 
  | 
 
输出样例 复制
数据范围与提示
5
abcdegfhijklnmopqrstuvwxyz
abcdegfhijklnmopqrstzyxwvu
dcbaegfhijklnmopqrstuvwxyz
abcdegfhijkwxyzlnmopqrstuv
abcdegfhijklnmouvwxyztsrqp
yes
yes
yes
no
yes
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | #include<bits/stdc++.h> using namespace std; int main(){     stack <char> st;     int n;     cin>>n;     while(n--){         string s;         cin>>s;         int len=s.size(),j=0;         for(int i=0;i<len;i++){             char ch=i+'a';             st.push(ch);             while(!st.empty() && st.top()==s[j]){                 st.pop(),j++;             }           }         if(j==len)cout<<"yes\n";         else cout<<"no\n";     } }
 
  |