双队列实现队列中元素排序

来源:互联网 发布:火狐javascript void 0 编辑:程序博客网 时间:2024/06/06 07:07

题目要求对一个队列中的元素进行排序,只允许使用一个临时队列,不能进行除去入队、出队、判空以外的任何操作。


实现方法为每次遍历队列,从中找出最小的元素,放入临时队列,遍历的过程是出队的过程,注意如果一个元素比当前的最小值大,则要放回队列当中,如果比当前的最小值小,则保存起来,暂时不放回队列中,发现更小的,把原来的最小值放入,更新最小值,在遍历完一次以后,将最小值存入临时队列。然后开始第二次遍历,注意每次遍历原队列中都会减少一个元素,因此共遍历队列N次,每次对队列N、N-1、N-2 ... 1这么多次出队操作来找最小值,在最后一次完成后临时队列中存放的就是排序好的结果,出队N次即可按非降序输出。


注意最坏的情况:如果最初的队列为非降序,则会造成大量的无用功,因此在原队列生成时就动态判断是否是非降序列,如果是,则直接将原队列打印。

#include<iostream>#include<stdio.h>using namespace std;#define INF   99999999#define MAXSIZE 100001typedef struct {int items[MAXSIZE];int front;int rear;}Queue;void initQueue(Queue *q){q->front = q->rear = 0;}bool isEmpty(Queue *q){return q->front == q->rear;}void AddQ(Queue *q, int item){if ((q->rear + 1)%MAXSIZE == q->front){// 为了区分空队列与满队列,必须保证rear和front不能再次碰面,因此要留出一个距离,提前判断是否添加后front=rear。printf("队列满");return;}q->rear = (q->rear + 1) % MAXSIZE;*(q->items + q->rear) = item;}int DeleteQ(Queue *q){if (q->rear == q->front){printf("队列空");return NULL;}q->front = (q->front + 1) % MAXSIZE;return *(q->items + q->front);}int main(){Queue q;Queue tempQ;initQueue(&q);initQueue(&tempQ);int N;scanf("%d", &N);int buffer;bool isRising = true;int last = 0, now = -1;for (int i = 0; i < N; i++){scanf("%d", &buffer);AddQ(&q, buffer);now = buffer;if (i > 0 && now < last){isRising = false;}last = now;}if (isRising){printf("%d", DeleteQ(&q));while (!isEmpty(&q)){printf(" %d", DeleteQ(&q));}printf("\n");return 0;}int min;for (int i = 0; i < N; i++){min = INF;for (int j = i; j < N; j++){buffer = DeleteQ(&q);if (buffer < min){if (min != INF) AddQ(&q, min);min = buffer;}else{AddQ(&q, buffer);}}AddQ(&tempQ, min);}printf("%d", DeleteQ(&tempQ));while (!isEmpty(&tempQ)){printf(" %d", DeleteQ(&tempQ));}printf("\n");return 0;}


0 0