1:快速排序
第一行个数,第二行数据
#include<bits/stdc++.h>
using namespace std;
int a[1e5 + 10] = {};
void quick(int L, int R){
int mid = a[(L + R) / 2];
//如果定下标中值,偶数时交换后 a[中值] 的值可能会改变
int i = L,j = R;//双指针(双下标)
do
{
while (a[i] < mid) i++;
while (a[j] > mid) j--;
if (i <= j)
{
swap(a[i], a[j]);
i++; j--;
}
} while (i <= j);//【但是一开始i不就是小于j的吗?】
//交换完毕后,j在左,i在右 【为啥?不是交换数组内容,i,j没有交换吗?】
//左区间为 [L,j]
//右区间为 [i,R]
if (L < j)quick(L, j);
if (i < R)quick(i, R);
}
int main(){
int n; cin >> n;
for (int i = 0; i < n; i++)cin >> a[i];
quick(0, n - 1);//【为什么是n-1?】
for (int i = 0; i < n; i++)cout << a[i] <<" ";
return 0;
}
2.DFS走迷宫
第一行两个数字N,M
接下来N行,每行M个字符,表示地图('#'障碍,'.'空地)
#include<bits/stdc++.h>
using namespace std;
int n,m;
int sx,sy;
//上下左右移动的位移数组
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};
//我们用vis表示已经走过的路,默认为0,走过为1
bool vis[505][505] = {};
//我们用maze存储迷宫
char maze[505][505] = {};
bool flag = 0;
void dfs(int x,int y){
if(maze[x][y] == 'E'){flag = 1;return;}//浅显子问题:走到终点就退出
//下面上下左右都来一次
for(int i = 0;i<4;i++){
//不妨用xx表示移动后的x
int xx = x + dx[i];
int yy= y + dy[i];
//下面判断是否在迷宫中
if(xx<=n && xx >=1 && yy<=m && yy>=1){//【哪来的m和n?】
//判断是否有路走,且是否已经走过
if(maze[xx][yy]!='#' && vis[xx][yy] == 0){
vis[xx][yy] = 1; //点(xx,yy)已经走过
dfs(xx,yy); //把这一点
//搜索从该点出发可以到哪里,直到死路才回头
}
}
}
}
int main()
{
while(cin>>n>>m){
//重置地图
memset(maze,0,sizeof(maze));
memset(vis,0,sizeof(vis));//【为什么要用memset?不分配行吗】
flag = 0; //默认说走不到终点
//导入迷宫到maze
for(int i = 1;i<=n;i++){
for(int j = 1;j<=m;j++){
cin>>maze[i][j];
//找起点
if(maze[i][j] == 'S'){
sx = i;sy = j;
}
}
}
//调用dfs,发送起点地址(sx,sy)
dfs(sx,sy);
if(flag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
3.BFS走迷宫
第一行两个数字N,M 接下来N行,每行M个字符,表示地图('#'障碍,'.'空地)
#include<bits/stdc++.h>
using namespace std;
int n,m;
int sx,sy;
//上下左右移动的位移数组
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};
//我们用vis表示已经走过的路,默认为0,走过为1
bool vis[505][505] = {};
//我们用maze存储迷宫
char maze[505][505] = {};
bool flag = 0;
void bfs(int x,int y){
queue<pair<int,int>> q; //存一组x y,用pair存
q.push({x,y});
while(!q.empty()){ //q非空进入循环
pair<int,int> temp = q.front(); q.pop();//【这啥?】
//不妨用xx表示移动后的x
int xx = temp.first;
int yy = temp.second;
if(maze[xx][yy] == 'E'){flag = 1;return;}//若走到终点就退出
//下面上下左右都来一次
for(int i = 0;i<4;i++){
int now_x = xx + dx[i];
int now_y = yy + dy[i];
//判断是否在迷宫中
if(now_x<=n && now_x >=1 && now_y<=m && now_y>=1){
//判断是否有路走,且是否已经走过
if(maze[now_x][now_y]!='#' && vis[now_x][now_y] == 0){
vis[now_x][now_y] = 1; //点(xx,yy)已经走过
q.push({now_x,now_y});//【这又是啥?】
}
}
}
}
}
int main()
{
while(cin>>n>>m){
//重置地图
memset(maze,0,sizeof(maze));
memset(vis,0,sizeof(vis));//【为什么要用memset?不分配行吗】
flag = 0; //默认说走不到终点
//导入迷宫到maze
for(int i = 1;i<=n;i++){
for(int j = 1;j<=m;j++){
cin>>maze[i][j];
//找起点
if(maze[i][j] == 'S'){
sx = i;sy = j;
}
}
}
//调用bfs,发送起点地址(sx,sy)
bfs(sx,sy);
if(flag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
4.层序遍历二叉树
第一行
第一行为二叉树的节点数 n
后面n行,每一个字母为节点,后两个字母分别为其左右儿子。‘*’为空。
#include<bits/stdc++.h>
using namespace std;
//定义二叉树
struct Tree {
char mark = '\0'; //当前节点的字母标号
int layer = 1; //层次(树的深度)
int left = -1; //默认没有左子树
int right = -1; //默认没有右子树
}p[30];
//层序遍历
void BFS(int root){
queue<int> q; //存节点的标号
q.push(root);//把root输入队列
while (!q.empty()) {
int now = q.front(); q.pop();//把队列第一个赋给now再丢掉【可是队列不是只有一个值吗?】
cout << p[now].mark << " ";
int L = p[now].left;
int R = p[now].right;
//子树非空加入队列【什么意思?】
if(L != -1)q.push(L);
if(R != -1)q.push(R);
//孩子的深度是父亲的深度+1
p[L].layer = p[now].layer + 1;
p[R].layer = p[now].layer + 1;
}
}
int main()
{
int n; cin >> n;
int root0 = -1; //整棵树的根节点,先设为-1,反正都要改
//输入部分
for (int i = 0; i < n; i++) {
string str; cin >> str;
//将3字母代号化为三个数字,第一个数字作为结构体下标,余2填到left和right
int root = str[0] - 'a'; //将字母数字化
//第一次把root0定位到root,便于发送根节点
if (i == 0)root0 = root; //字母a 则 root = 0
int L = str[1] - 'a'; //字母b,L = 1
int R = str[2] - 'a'; //字母c,R = 2
p[root].mark = str[0]; //把实际的字母填入该字母代号为下标的结构体mark字段
if (str[1] != '*') p[root].left = L; //不是 * 就录入左子树,是 * 保持 -1 不动
if (str[2] != '*')p[root].right = R; //同上,录入右子树
}
BFS(root0); //以整棵树的根节点开始层序遍历
return 0;
}