查找典型例题

🍊前面我的博客中已经介绍了多种查找方法,这篇博客我将运用这些方法解决一些实际的例题,如果有不懂的地方可以回去看前几篇博客哦~

一、求第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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小瑾比个耶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值