数据结构刷题
山理工数据结构刷题
专题1--顺序表
简单的顺序表归并
#include <bits/stdc++.h>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int, int> PII;
const int N = 100008;
signed main () {
vector<int> a;
vector<int>b;
vector<int> c;
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
a.push_back(x);
}
for (int i = 1; i <= m; i++) {
int x;
cin >> x;
b.push_back(x);
}
int cnt1 = 0;
int cnt2 = 0;
while (cnt1 < (int)a.size() && cnt2 < (int)b.size()) {
if (a[cnt1] <= b[cnt2]) {
c.push_back(a[cnt1]);
cnt1++;
} else {
c.push_back(b[cnt2]);
cnt2++;
}
}
if (cnt1 == (int)a.size()) {
while (cnt2 < (int)b.size()) {
c.push_back(b[cnt2]);
cnt2++;
}
} else {
while (cnt1 < (int)a.size()) {
c.push_back(a[cnt2]);
cnt1++;
}
}
for (auto y : c) {
cout << y << ' ';
}
cout << '\n';
return 0;
}
二分题目模板题
#include <bits/stdc++.h>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int, int> PII;
const int N = 100008;
int n;
int a[N];
signed main () {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
int m;
cin >> m;
while (m--) {
int x;
cin >> x;
int l = 0, r = n + 1;
while (l + 1 < r) {
int mid = (l + r) / 2;
if (a[mid] < x ) {
l = mid;
} else {
r = mid;
}
}
if (a[r] == x) {
cout << r << '\n';
} else {
cout << "No Found!\n";
}
}
return 0;
}
专题2--栈和队列
思路:遇到左括号均进栈,右括号进行判断
不匹配有三种情况:1.右括号与左括号不匹配 2.右括号多余(栈空了) 3. 左括号多余(栈非空)
#include <bits/stdc++.h>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int, int> PII;
const int N = 100008;
signed main () {
string str;
while (getline(cin, str)) {
stack<char> s;
bool flag = true;
for (int i = 0; i < (int)str.size(); i++) {
if (str[i] == '(' || str[i] == '{' || str[i] == '[') {
s.push(str[i]);
}
if (str[i] == ')' || str[i] == '}' || str[i] == ']') {
if (s.empty()) {//运算的时候栈空了
flag = false;
break;
}
char temp = s.top();
if (temp == '(' && str[i] == ')') {
s.pop();
} else if (temp == '{' && str[i] == '}') {
s.pop();
} else if (temp == '[' && str[i] == ']') {
s.pop();
} else {//如果不匹配的话
flag = false;
}
}
}
if (!s.empty()) {//最后栈不空
flag = false;
}
if (flag) {
cout << "yes" << '\n';
} else {
cout << "no" << '\n';
}
}
return 0;
}
专题3--串和数组
使用string中的函数
#include <bits/stdc++.h>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int, int> PII;
const int N = 100008;
void solve() {
string s1, s2;
cin >> s1 >> s2;
int ans = s1.find(s2);
if (ans == (int)s1.npos) {
cout << "::>_<::" << '\n';
} else {
cout << ans + 1 << '\n';
}
}
signed main () {
std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
int t;
cin >> t;
while (t) {
solve();
t--;
}
return 0;
}
使用find函数偷懒
#include <bits/stdc++.h>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int, int> PII;
const int N = 100008;
signed main () {
string s1, s2;
while (cin >> s1) {
cin >> s2;
if (s1.find(s2) == s1.npos) {
no;
} else {
yes;
}
}
return 0;
}
专题4--二叉树
#include <bits/stdc++.h>
using namespace std;
typedef struct Binode {
char data;
struct Binode* lchild;
struct Binode* rchild;
} BiNode, *BiTree;
char str[200];
int cnt = 0;
void CreateBitree(BiTree &T) {//创建二叉树
char ch;
ch = str[cnt++];
if (ch == ',') {
T = NULL;
} else {
T = new Binode;
T->data = ch;
CreateBitree(T->lchild);
CreateBitree(T->rchild);
}
}
int LeadCount(BiTree T) {//统计叶子结点
if (T == NULL) {
return 0;
}
if (T->lchild == NULL && T->rchild == NULL) {
return 1;
} else {
return LeadCount(T->lchild) + LeadCount(T->rchild);
}
}
void DLR(BiTree T) {
if (T == NULL) {
return;
} else {
cout << T->data;
DLR(T->lchild);
DLR(T->rchild);
}
}
int main () {
while (scanf("%s", str) != EOF) {
cnt = 0;
BiTree root = NULL;
CreateBitree(root);
// DLR(root);
cout << LeadCount(root) << '\n';
}
return 0;
}
专题5--二叉查找树和平衡二叉树
#include <bits/stdc++.h>
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int, int> PII;
const int N = 100008;
typedef struct BSNode {
int data;
struct BSNode* lchild;
struct BSNode* rchild;
} BSNode, *BSTree;
void BSinsert(BSTree &T, int key) {
if (T == NULL) {
T = new BSNode;
T->lchild = NULL;
T->rchild = NULL;
T->data = key;
}
else if (key < T->data) {
BSinsert(T->lchild, key);
} else {
BSinsert(T->rchild, key);
}
}
void LDR(BSTree T) {
if (T == NULL) {
return;
}
LDR(T->lchild);
cout << T->data << ' ';
LDR(T->rchild);
}
int main () {
int n;
while (scanf("%d", &n) != EOF) {
BSTree T = NULL;
for (int i = 1; i <= n; i++) {
int key;
cin >> key;
BSinsert(T, key);
}
LDR(T);
printf("\n");
}
return 0;
}
专题6--堆、哈夫曼树
专题9--图的遍历DFS&BFS
#include <bits/stdc++.h>
using namespace std;
const int N = 200;
int g[N][N] = {0};//邻接矩阵存图
bool vis[N] = {false};//标记数组
int k, m;
void dfs(int x) {
cout << x << ' ';//打印结果
vis[x] = true;//标记为已经访问
for (int i = 0; i < k; i++) {//从0遍历到k
if (vis[i] == false && g[x][i] == 1) { //该点没被访问过,并且该点可以联通
dfs(i); //递归调用这个函数
}
}
}
int main () {
int t;
cin >> t;
while (t--) {
memset(g, 0, sizeof(g));
memset(vis, false, sizeof (vis));//每次对数组进行初始化
cin >> k >> m;
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
g[u][v] = 1; //建立无向图
g[v][u] = 1; //建立无向图
}
dfs(0);//开始搜索
cout << '\n';
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 120;
struct Node {
int data;//数据域
struct Node* next;//指针域
};
//typedef struct node Node;
Node* head[N];//头指针数组
bool vis[N];//标记数组
int n, m, s;
Node* p = NULL;
void bfs(int s) {
for (int i = 0; i < m; i++) {//冒泡排序
for (Node *p = head[i] -> next; p; p = p -> next) {
for (Node *q = p -> next; q; q = q -> next) {
if (p -> data > q -> data) {
int tmp = p -> data;
p -> data = q -> data;
q -> data = tmp;
}
}
}
}
//下面开始bfs
int q = 0;
queue <int > Q;
Q.push(s);//将起点放入队列
vis[s] = true; //将起点标记为已经访问
while (!Q.empty()) { //只要队列不为空
q = Q.front();
cout << q << ' ';
Q.pop();
for (p = head[q]->next; p != NULL; p = p->next) {
if (vis[p->data] == false) { //如果未访问过
vis[p->data] = true; //现在进行访问
Q.push(p->data);
}
}
}
}
int main () {
int k;
cin >> k;
for (int i = 0; i < N; i++) {
head[i] = new Node; //初始化头指针数组
}
while (k--) {
memset(vis, 0, sizeof vis); //初始化标记数组
cin >> n >> m >> s;
for (int i = 0; i < n; i++) {
head[i]->next = NULL; //初始化头指针数组
}
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
p = new Node; //建立新节点
p->data = v;
p->next = head[u]->next; //让新节点指向首元节点
head[u]->next = p; //头插法
p = new Node;
p->data = u;
p->next = head[v]->next;
head[v]->next = p; //头插法
}
bfs(s);//从开始搜索
printf("\n");
}
return 0;
}
专题14--排序
希尔排序是优化版的插入排序,题目让写出增量为n/2和1的一次希尔排序之后的结果
#include <bits/stdc++.h>
using namespace std;
/*
a为待排序的数组,dk为该趟的增量,n为数组元素
*/
void Shellsort(int a[], int dk, int n) {
int i, j;
for ( i = dk + 1; i <= n; i++) {
if (a[i] < a[i - dk]) {//如果后面的元素更大
a[0] = a[i];//讲需要插入的元素放入哨兵位置
//从当前位置向前插入
for ( j = i - dk; j > 0 && (a[0] < a[j]); j = j - dk) {
a[j + dk] = a[j];
}
a[j + dk] = a[0];
}
}
}
int a[10005];
int main () {
int n;
while (cin >> n) {
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
Shellsort(a, n / 2, n);//增量为n/2的时候
for (int i = 1; i <= n; i++) {
cout << a[i] << ' ';
}
printf("\n");
Shellsort(a, 1, n);//增量为1的时候
for (int i = 1; i <= n; i++) {
cout << a[i] << ' ';
}
printf("\n");
}
return 0;
}