题目描述
小蓝是一名计算机专业的学生,最近他学习了《操作系统》、《数据结构》 等课程,他设计了一种名为 “冷热数据队列” 的数据结构,来对数据页进行管理。
冷热数据队列 q 可以看做由两个子队列组成:长度为 n1 的热数据队列 q1 和长度为 n2 的冷数据队列 q2 。当我们需要访问某个数据页 p 时:
1)若 p 不在队列 q 中(即既不在 q1 中,也不在 q2 中),则加载数据页 p ,并插入到 q2 的首部。
2)若 p 已经在队列 q 中,则将 p 移动至 q1 首部。
3)当 q1 或 q2 队列容量不足时,会将其尾部的数据页淘汰出去。
4)当 q1 已满,但 q2 未满时,从 q1 中淘汰出的数据页会移动到 q2 首部。
输入格式
输入的第一行包含两个正整数 n1, n2 ,用一个空格分隔。
第二行包含一个整数 m ,表示操作次数。
第三行包含 m 个正整数 v1, v2, · · · , vm ,表示依次访问到的数据页的编号, 相邻整数之间使用一个空格分隔。
输出格式
输出两行。
第一行包含若干个整数,相邻整数之间使用一个空格分隔,依次表示 q1 中 的数据页。
第二行包含若干个整数,相邻整数之间使用一个空格分隔,依次表示 q2 中 的数据页。
样例输入
3 3 10 1 2 3 4 3 2 2 1 3 4
样例输出
4 3 2 1
提示
【样例说明】
【评测用例规模与约定】
对于 20% 的评测用例,1 ≤ n1, n2 ≤ 10 ,1 ≤ m ≤ 10 ;
对于 40% 的评测用例,1 ≤ n1, n2 ≤ 20 ,1 ≤ m ≤ 100 ;
对于 60% 的评测用例,1 ≤ n1, n2 ≤ 100 ,1 ≤ m ≤ 1000 ;
对于 80% 的评测用例,1 ≤ n1, n2 ≤ 103 , 1 ≤ m ≤ 104 ;
对于所有评测用例,1 ≤ n1, n2 ≤ 104 ,1 ≤ m ≤ 105 ,0 ≤ vi ≤ 104 。
思路
入队出队这种可以用结构体来做,设两个结构体,代表两个队列,根据情况设置入队出队的操作
有新数据首先在两队列中查找,都不在的话就加入第二队,并删除多余元素;在第一队就进行队内调整,可以先删去对应元素,再在首位添加;在第二队就将对应元素移动到第一队,并将多出的元素移动到第二队,因为第二队的元素移动,所以一定处于不满状态
结构体很久没用了,很生疏,又因为结构体末尾的指针我不会用,所以就没设,而是用一个函数查找末尾元素
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
typedef struct QNode {
ElemType data;
struct QNode* next;
}QNode;
typedef struct Queue {
struct QNode* front;
ElemType length;
}Queue;
void InitQueue(Queue* Q, int n){
Q->front = NULL;
Q->length = n;//记录队列最大长度
}
int inQueue(int v, Queue* Q) {//检测数据在其中,如果有数据就同时删除
if (Q->front == NULL)
return 0;
QNode* q = Q->front;
if (q->data == v) {
Q->front = q->next;
return 1;
}
QNode* q2 = q->next;
while (q2) {
if (q2->data == v) {//同时删除数据,便于之后添加
q->next = q2->next;
free(q2);
return 1;
}
q = q->next;
q2 = q2->next;
}
return 0;
}
int QueueLen(Queue* Q) {//当前数据长度
int length = 0;
if (Q->front == NULL)
return 0;
QNode *q;
q = Q->front;
while (q) {
length++;
q = q->next;
}
return length;
}
void joinQueue(Queue* Q, int v) {//加入首位元素
struct QNode* q = (struct QNode*)malloc(sizeof(struct QNode));
q->data = v;
q->next = Q->front;
Q->front = q;
}
void deleteQueue(Queue* Q) {//删除末尾元素
QNode *q1,*q2;
q1 = Q->front;
if (!q1->next) {
Q->front = NULL;
free(q1);
return;
}
q2 = q1->next;
while (q2&&q2->next) {
q1 = q1->next;
q2 = q2->next;
}
q1->next = NULL;
free(q2);
}
void deletedQueueMid(Queue* Q, int v) {//删除其中元素
QNode *q1,*q2;
q1 = Q->front;
if (q1->data == v) {
Q->front = q1->next;
free(q1);
return;
}
q2 = q1->next;
while (q2) {
if (q2->data == v) {
q1->next = q2->next;
free(q2);
return;
}
q1 = q1->next;
q2 = q2->next;
}
}
int findLost(Queue* Q) {//查找末尾元素
QNode* q1=Q->front;
int k = 0;
while (q1) {
k = q1->data;
q1 = q1->next;
}
return k;
}
int main() {
int n1, n2;
long long m;
int i,v;
struct Queue* q1 = (struct Queue*)malloc(sizeof(struct Queue));
struct Queue* q2 = (struct Queue*)malloc(sizeof(struct Queue));
scanf("%d %d", &n1, &n2);
InitQueue(q1, n1);
InitQueue(q2, n2);
scanf("%lld", &m);
for (i = 0;i < m;i++) {
scanf("%d", &v);
int inQ1 = inQueue(v, q1);
int inQ2 = inQueue(v, q2);
if (!inQ1 && !inQ2) {//不在两表内
joinQueue(q2, v);
if (QueueLen(q2) > n2) {//数量过多,删除
deleteQueue(q2);
}
}
else if (inQ1) {//在第一层中
joinQueue(q1, v);
}
else {//在第二层中
joinQueue(q1, v);
if (QueueLen(q1) > n1) {//超出空间
int k = findLost(q1);//末尾元素
deleteQueue(q1);
joinQueue(q2, k);
}
}
}
QNode *q = q1->front;
while (q) {
printf("%d ", q->data);
q = q->next;
}
printf("\n");
q = q2->front;
while (q) {
printf("%d ", q->data);
q = q->next;
}
printf("\n");
return 0;
}