🍊前面我的博客中已经介绍了多种查找方法,这篇博客我将运用这些方法解决一些实际的例题,如果有不懂的地方可以回去看前几篇博客哦~
一、求第k大的树
【问题描述】 求n个数中第k大的数
【输入形式】 第一行n k,第二行为n个数,都以空格分开
【输出形式】 第k大的数
【样例输入】
10 3
18 21 11 26 12 2 9 33 43 28【样例输出】
28
#include<iostream>
#define max 100 // 定义数组最大容量为100
using namespace std;
// 快速排序的分区函数
int part(int a[], int low, int high) {
int p = a[low]; // 选择第一个元素作为基准值(pivot)
while (low < high) { // 循环直到low和high相遇
// 从右向左找第一个小于基准值的元素
while (low < high && a[high] >= p)
--high;
a[low] = a[high]; // 将找到的小于基准值的元素放到左边
// 从左向右找第一个大于基准值的元素
while (low < high && a[low] <= p)
++low;
a[high] = a[low]; // 将找到的大于基准值的元素放到右边
}
a[low] = p; // 将基准值放到最终位置
return low; // 返回基准值的最终位置
}
// 快速排序的递归函数
void quicksort(int a[], int low, int high) {
if (low < high) { // 递归终止条件:子数组长度大于1
int p = part(a, low, high); // 获取分区点
quicksort(a, low, p - 1); // 递归排序左半部分
quicksort(a, p + 1, high); // 递归排序右半部分
}
}
int main() {
int n, k; // n表示数组元素个数,k表示要找的第k大的元素
cin >> n >> k; // 输入n和k
int a[max]; // 声明数组
for (int i = 0; i < n; i++)
cin >> a[i]; // 输入数组元素
quicksort(a, 0, n - 1); // 对数组进行快速排序
// 输出第k大的元素(排序后升序排列,所以a[n-k]就是第k大的元素)
cout << a[n - k];
return 0;
}
二、查找3个数组的最小共同元素
【问题描述】查找3个数组的最小共同元素
【输入形式】三个数组,均以0代表输入结束
【输出形式】最小共同元素
【样例输入】1 3 5 7 8 9 0
2 4 6 8 10 12 14 16 18 0
-1 3 8 16 18 19 20 168 198 0
【样例输出】8
#include<iostream>
#define max 100 // 定义数组最大容量为100
using namespace std;
// 冒泡排序函数,对数组进行升序排序
void bubblesort(int a[], int n) {
for (int i = 0; i < n - 1; i++) { // 外层循环控制排序轮数
bool flag = false; // 标志位,用于优化(如果某轮没有交换,说明已有序)
for (int j = 0; j < n - i - 1; j++) { // 内层循环控制每轮比较次数
if (a[j] > a[j + 1]) { // 如果前一个元素大于后一个元素
// 交换相邻元素
int t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
flag = true; // 发生交换,设置标志位为true
}
}
if (flag == false) // 如果一轮比较没有发生交换,提前结束排序
return;
}
}
// 查找三个数组中共同的最小元素
void Find(int a[], int b[], int c[], int n1, int n2, int n3) {
int min; // 存储当前检查的元素
for (int i = 0; i < n1; i++) { // 遍历第一个数组(已排序,从小到大)
int flag = 0; // 标志位,记录当前元素是否在另外两个数组中出现
min = a[i]; // 获取当前元素
// 检查当前元素是否在第二个数组中
for (int j = 0; j < n2; j++) {
if (b[j] == min) { // 如果找到相同元素
flag++; // 标志位加1
break; // 跳出循环
}
}
// 检查当前元素是否在第三个数组中
for (int k = 0; k < n3; k++) {
if (c[k] == min) { // 如果找到相同元素
flag++; // 标志位加1
break; // 跳出循环
}
}
// 如果当前元素在三个数组中都存在(flag==2是因为在b和c中找到了)
if (flag == 2) {
cout << min; // 输出这个共同的最小元素
return; // 找到后立即返回
}
}
}
int main() {
int a[max], b[max], c[max]; // 定义三个数组
int n1 = 0, n2 = 0, n3 = 0; // 分别记录三个数组的实际长度
// 输入第一个数组,以0作为结束标志
for (int i = 0; ; i++) {
int x;
cin >> x;
if (x == 0) break; // 输入0表示结束
a[i] = x;
n1++; // 数组长度加1
}
// 输入第二个数组,以0作为结束标志
for (int i = 0; ; i++) {
int x;
cin >> x;
if (x == 0) break;
b[i] = x;
n2++;
}
// 输入第三个数组,以0作为结束标志
for (int i = 0; ; i++) {
int x;
cin >> x;
if (x == 0) break;
c[i] = x;
n3++;
}
// 对三个数组分别进行排序
bubblesort(a, n1);
bubblesort(b, n2);
bubblesort(c, n3);
// 查找三个数组中共同的最小元素
Find(a, b, c, n1, n2, n3);
return 0;
}
三、查找一个循环顺序数组的最小元素
【问题描述】以循环排列的一组顺序的数据,存储在一维数组中,查找最小元素并输出。
【输入形式】一组数据,以0结束输入
【输出形式】最小元素
【样例输入】7 9 11 1 3 5 0
【样例输出】1
#include<iostream>
#define max 100 // 定义数组最大容量为100
using namespace std;
// 冒泡排序函数:对整型数组进行升序排序
// 参数说明:
// a[] - 待排序的数组
// n - 数组的实际长度
void bubblesort(int a[], int n) {
// 外层循环控制排序轮数,最多需要n-1轮
for(int i = 0; i < n - 1; i++) {
bool flag = false; // 交换标志位,用于优化算法
// 内层循环控制每轮的比较和交换
// 每轮结束后,最大的元素会"冒泡"到数组末尾
for(int j = 0; j < n - i - 1; j++) {
// 如果前一个元素大于后一个元素,则交换它们
if(a[j] > a[j + 1]) {
// 交换相邻元素
int t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
flag = true; // 标记发生了交换
}
}
// 如果一轮比较中没有发生交换,说明数组已经有序,可以提前结束排序
if(flag == false)
return;
}
}
int main() {
int a[max]; // 声明一个最大容量为100的整型数组
int n = 0; // 记录数组实际长度
// 输入数组元素,以0作为结束标志
cout << "请输入数组元素(以0结束输入):" << endl;
for(int i = 0; ; i++) {
int x;
cin >> x; // 读取输入的数字
// 如果输入0,结束输入
if(x == 0)
break;
a[i] = x; // 将输入的数字存入数组
n++; // 数组长度加1
}
// 对数组进行冒泡排序(升序)
bubblesort(a, n);
// 输出排序后的数组中的最小值(即第一个元素)
cout << "数组中的最小值是:" << a[0] << endl;
return 0;
}