Я пытаюсь сделать программу быстрой сортировки. Я просто не мог понять, почему и как появляется эта ошибка. Я пробовал каждый метод в Интернете, но я не могу понять проблему. Если я делаю это с массивом вместо вектора, я получаю правильный вывод, но с ошибкой вектора.
Мои ошибки:
.\quicksort.cpp:7:28: error: cannot convert 'std::vector<double>' to 'double' in initialization
Double pivot = values[end];
.\quicksort.cpp:10:19: error: no match for 'operator<=' (operand types are 'std::vector<double>' and 'double')
If (values[i] <= pivot) {
Как тогда преобразовать vector<double> в двойное число?
Вот мой код:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int partition(vector<double> *values, int start, int end) {
double pivot = values[end];
int pIndex = start;
for (int i=start; i<end; i++) {
if (values[i] <= pivot) {
swap(values[i], values[pIndex]);
pIndex++;
}
}
swap(values[pIndex], values[end]);
return pIndex;
}
void quicksort(vector<double> *values, int start, int end) {
if (start<end) {
int pIndex;
pIndex = partition(values, start, end);
quicksort(values, start, pIndex-1);
quicksort(values, pIndex+1, end);
}
}
int main() {
int n;
cin >> n;
vector<double> values(n);
for (int i = 0; i < n; i++) {
cin >> values[i];
}
quicksort(values, 0, n-1);
for (int j=0; j<n; j++) {
cout<<values[j]<<" ";
}
return 0;
}
Как исправить эти ошибки?
Ссылки, а не указатели
int partition(vector<double>& values, int start, int end) {
void quicksort(vector<double>& values, int start, int end) {
Если вы использовали указатель (но вы не должны), правильный код будет
double pivot = (*values)[end];
Указатели — это не то же самое, на что они указывают, вы должны использовать * или ->, чтобы добраться до объекта, на который указывает указатель. Вам не нужно делать это со ссылками.
Массивы особенные, они автоматически преобразуются в указатели при передаче в функцию. Это правило не применяется к объектам любого другого типа, так что забудьте о массивах. Что касается разницы между указателями и ссылками, я уверен, что вы можете найти это в Google (это более серьезная тема, чем я могу затронуть в этом комментарии), и выбор того, что использовать, иногда зависит от вашего мнения.
void quicksort(vector<double> &values, const int start, const int end);
int partition(vector<double> &values, const int start, const int end)
И ваша ошибка времени компиляции исчезла, с указателем на объект, который вам нужен для вызова вашей функции следующим образом:
quicksort(&values, 0, n - 1);
Потому что вам нужен его адрес (на самом деле он нужен вашему указателю).
И вам нужно использовать operator[] из std::vector, что сначала нужно получить std::vector объект из указателя на него:
double pivot = (*values)[end];
Как вы видите, это уродливо и может быть сложно, поэтому в таких ситуациях лучше использовать ссылки вместо указателя.
Ваши функции разделения и быстрой сортировки принимают указатели в качестве параметров, а не ссылочных значений.
Ваши функции должны быть объявлены как таковые:
int partition(vector<double> &values, int start, int end)
void quicksort(vector<double> &values, int start, int end)
Причина, по которой вы получаете ошибку, заключается в том, что, поскольку параметр values является указателем, когда вы используете метод доступа к массиву ([i]), он предполагает, что values являются массивом векторов, и возвращает вектор, а не двойной.
Решение сработало. В чем основное различие между указателями и ссылками? Как узнать, что и когда использовать? Кроме того, когда я использовал массивы, это работало, но не с векторами. Как?