QSort没有正确排序,除非之后再排序一次

时间:2015-04-10 08:34:41

标签: c++ arrays sorting

我正在尝试通过重载“+”运算符来相互添加两个优先级队列。

// Overloading add operator (+)
template <class T> PrioQueue<T> operator + (PrioQueue<T> &a, PrioQueue<T> &b) {
    // Create a new queue that's big enough to hold our 2 queues
    PrioQueue<T> newPrioQueue(a.num_items + b.num_items);

    // Push all items to the new queue
    // all items will be sorted on pushtime (get it? Instead of runtime? Haha... Ha...)
    for (T * element = a.bottom_; element < a.bottom_ + a.num_items; element++) {
        newPrioQueue.push(*element);
        std::cout << newPrioQueue;
    }

    // Push all items to the new queue
    // all items will be sorted on pushtime
    for (T * element = b.bottom_; element < b.bottom_ + b.num_items; element++) {
        newPrioQueue.push(*element);
        std::cout << newPrioQueue;
    }

    // This one is needed - why?
    newPrioQueue.sort();

    std::cout << newPrioQueue;

    // New queue is done, return it.
    return newPrioQueue;
}

这是我的PrioQueue的push功能:

void push(T t) {
    if (!full()) {
        *top_ = t;
        top_++;
        num_items++;

        // Sort items using qsort
        qsort(bottom_, num_items, sizeof(T), compareFunction);
    } else {
        std::cout << "Queue is full" << endl;
    }

};

如您所见,PrioQueue将在每push后排序。但是,在组合两个数组之后需要最后一种!检查此输出:

Queue has 1 item(s): 429
Queue has 2 item(s): 429|123
Queue has 3 item(s): 429|123|24
Queue has 4 item(s): 429|123|24|24
Queue has 5 item(s): 429|123|24|24|3
Queue has 6 item(s): 429|123|24|24|3|2
Queue has 7 item(s): 24|123|24|429|3|2|1
Queue has 7 item(s): 429|123|24|24|3|2|1

倒数第二行是错误。它突然扰乱了所有数据!

为什么会这样?

编辑:这是我的CompareFunction:

static int compareFunction (const void * a, const void * b) {
    // Relies on overloading of the "<" operator with non-std objects
    return (*(T*)a < *(T*)b);
}

这是输入:

intQueue1.push(24);
intQueue1.push(429);
intQueue1.push(123);

intQueue2.push(1);
intQueue2.push(2);
intQueue2.push(3);
intQueue2.push(24);

intQueue3 = intQueue1 + intQueue2;

2 个答案:

答案 0 :(得分:3)

可能错了,但你的compareFunction

static int compareFunction (const void * a, const void * b) {
    // Relies on overloading of the "<" operator with non-std objects
    return (*(T*)a < *(T*)b);
}

应该返回1,0或-1并返回true或false ...

答案 1 :(得分:1)

如果没有充分的理由,你不应该在C ++中使用qsort。尝试

std::sort(bottom_, bottom_+num_items);

这将使用<进行比较,因此如果您的类型覆盖该运算符,则无需提供比较器。

如果你真的想因某种原因使用qsort,那么请注意它只适用于简单的可复制类型,需要不同形式的比较器,返回负值,零或正值分别表示小于,等于或大于。你需要像

这样的东西
T & aa = reinterpret_cast<T&>(a);
T & bb = reinterpret_cast<T&>(b);
if (aa < bb) return -1;
if (bb < aa) return 1;
return 0;