中位数

/*这段代码能够取到中位数的原因在于它使用了两个优先队列(priority_queue),并且根据特定的规则对元素进行插入和删除操作。

具体来说,代码中使用了两个优先队列:q1和q2。q1中的元素按升序排列,而q2中的元素按降序排列。这样设计的原因是为了使得两个队列中的元素能够交替地取到中位数。

在每次循环中,根据输入的整数x与队列q2的顶部元素的大小关系,将x插入到适当的队列中。如果x大于等于q2的顶部元素,则将x插入到q2中;否则,将x插入到q1中。

如果队列q2的大小大于队列q1的大小加1,说明当前中位数应该在q2中。为了保持队列有序,需要将q2的顶部元素(即当前中位数)移动到q1中。

在输出中位数时,如果当前是奇数次循环,则根据队列的大小关系选择输出队列中的最大元素。如果q1的大小大于q2的大小,则输出q1中的最大元素;否则,输出q2中的最大元素。

通过这样的规则和操作,代码能够保证每次输出的都是当前输入序列的中位数。

*/

#include <cstdio>  // 引入cstdio库,用于输入输出流操作  
#include <queue>   // 引入queue库,用于使用优先队列数据结构  
using namespace std;  // 使用命名空间std,以便简化代码书写  
  
int main() {  // 主函数,程序的入口点  
    int n;  // 声明一个整数变量n,用于存储输入的数量  
    scanf("%d", &n);  // 从标准输入读取一个整数,并存储到变量n中  
  
    priority_queue<int> q1;  // 声明一个优先队列q1,用于存储整数  
    priority_queue<int, vector<int>, greater<int> > q2;  // 声明一个优先队列q2,用于存储整数,队列的比较函数为greater<int>,表示队列中的元素按降序排列  
  
    for (int i = 1; i <= n; i++) {  // 循环n次,每次读取一个整数  
        int x;  // 声明一个整数变量x,用于存储输入的整数  
        scanf("%d", &x);  // 从标准输入读取一个整数,并存储到变量x中  
  
        if (q2.empty() || x >= q2.top()) {  // 如果队列q2为空或者输入的整数x大于等于队列q2的顶部元素  
            q2.push(x);  // 将输入的整数x插入队列q2中  
            if (q2.size() > q1.size() + 1) {  // 如果队列q2的大小大于队列q1的大小加1  
                int t = q2.top();  // 将队列q2的顶部元素赋值给变量t  
                q2.pop();  // 从队列q2中删除顶部元素  
                q1.push(t);  // 将变量t插入队列q1中  
            }  
        } else {  // 如果队列q2不为空且输入的整数x小于队列q2的顶部元素  
            q1.push(x);  // 将输入的整数x插入队列q1中  
            if (q1.size() > q2.size() + 1) {  // 如果队列q1的大小大于队列q2的大小加1  
                int t = q1.top();  // 将队列q1的顶部元素赋值给变量t  
                q1.pop();  // 从队列q1中删除顶部元素  
                q2.push(t);  // 将变量t插入队列q2中  
            }  
        }  
  
        if (i % 2 == 1) {  // 如果当前是奇数次循环(即输出的次序为先输出q1中的最大元素,再输出q2中的最大元素)  
            if (q1.size() > q2.size()) {  // 如果队列q1的大小大于队列q2的大小  
                printf("%d\n", q1.top());  // 输出队列q1中的最大元素  
            } else {  // 否则  
                printf("%d\n", q2.top());  // 输出队列q2中的最大元素  
            }  
        }  
    }  
    return 0;  // 返回0,表示程序正常结束  
}


这段代码是一个C++程序,主要用于从标准输入读取一系列的整数,并使用两个优先队列(priority_queue)来交替地输出两个队列中的最大元素。

以下是代码的详细功能描述:

  1. 引入了cstdioqueue两个库,分别用于输入输出流操作和优先队列数据结构。

  2. 在主函数中,首先从标准输入读取一个整数n,表示接下来要输入的整数的数量。

  3. 声明了两个优先队列:q1q2。其中,q1用于存储整数,而q2也用于存储整数,但队列中的元素按降序排列。

  4. 使用一个循环,循环次数由输入的整数n决定,每次循环执行以下操作:

    • 声明一个整数变量x,用于存储从标准输入读取的下一个整数。
    • 根据以下条件之一,将整数x插入到适当的优先队列中:
      • 如果队列q2为空或者输入的整数x大于等于队列q2的顶部元素,则将x插入到队列q2中。
      • 否则,将x插入到队列q1中。
    • 如果队列q2的大小大于队列q1的大小加1,则执行以下操作:
      • 将队列q2的顶部元素赋值给变量t
      • 从队列q2中删除顶部元素。
      • 将变量t插入到队列q1中。
    • 如果当前是奇数次循环(即输出的次序为先输出队列q1中的最大元素,再输出队列q2中的最大元素),则根据以下条件之一输出队列中的最大元素:
      • 如果队列q1的大小大于队列q2的大小,则输出队列q1中的最大元素。
      • 否则,输出队列q2中的最大元素。
  5. 循环结束后,程序返回0,表示正常结束。

 

posted @ 2024-01-06 11:46  Boy^  阅读(43)  评论(0)    收藏  举报