Как я могу отсортировать массив двойных указателей на основе значений, на которые они указывают?

Я пытаюсь создать функцию на C/С++ для сортировки массива и замены каждого значения его «оценкой» или рангом. Он принимает массив двойных указателей на массив целых чисел и сортирует двойные указатели на основе разыменованного значения целых чисел. Я пытался довольно много раз заставить его работать, но не могу его сбросить. Опять же, он должен сортировать двойные указатели на основе значений, на которые они указывают. Вот что у меня есть:

void SortArray( int ** pArray, int ArrayLength )
{
  int i, j, flag = 1;     // set flag to 1 to begin initial pass
  int * temp;             // holding variable orig with no *
  for(i = 1; (i <= ArrayLength) && flag; i++)
  {
    flag = 0;
    for (j = 0; j < (ArrayLength -1); j++)
    {
        if (*pArray[j+1] > *pArray[j])    // ascending order simply changes to <
        { 
            temp = &pArray[j];            // swap elements
            pArray[j] = &pArray[j+1];
            pArray[j+1] = &temp;
            flag = 1;                     // indicates that a swap occurred.
        }
    }
  }
}

person Ed.    schedule 20.08.2008    source источник
comment
См. также stackoverflow.com/questions/5632832/, в котором я привожу два примера. Использование O (log (n)) и не O (N ^ 2)   -  person elcuco    schedule 01.01.2013


Ответы (5)


Вы близко. Вы ссылаетесь на адрес элементов массива при обмене, что не обязательно. Элементы в массиве являются указателями, и их нужно поменять местами.

Увидеть ниже:

void SortArray( int ** pArray, int ArrayLength )
{
    int i, j, flag = 1;    // set flag to 1 to begin initial pass
    int * temp;             // holding variable orig with no *
    for(i = ArrayLength - 1; i > 0 && flag; i--)
    {
        flag = 0;
        for (j = 0; j < i; j++)
        {
            if (*pArray[j] > *pArray[j+1])      // ascending order simply changes to <
            { 
                temp = pArray[j];             // swap elements
                pArray[j] = pArray[j+1];
                pArray[j+1] = temp;
                flag = 1;               // indicates that a swap occurred.
            }
        }
    }
}

Кроме того, ознакомьтесь с этим прекрасным сообщением в блоге о сортировке пузырьком. на случай, если вам интересно (извините, бессовестная затычка :)). Надеюсь, это поможет вам с домашним заданием;)


Изменить: обратите внимание на тонкую «оптимизацию», когда вы отсчитываете от длины массива и увеличиваете только до «i» во внутреннем цикле. Это избавит вас от ненужного повторного анализа элементов, которые уже были отсортированы.

person OJ.    schedule 20.08.2008

Хех, это не домашнее задание.

Если это так, рассмотрите возможность использования STL для управления массивами и сортировки. Его легче разрабатывать и поддерживать, а алгоритм std::sort асимптотически быстрее, чем пузырьковая сортировка.

person Brian Ensink    schedule 20.08.2008

Вам следует рассмотреть возможность использования std::swap() для обмена. Если вы это сделаете, назовите это так:

swap( obj1, obj2 );

скорее, чем:

std::swap( obj1, obj2 );

Поскольку семантика первого вызова позволит правильному поиску пространства имен найти правильную перегрузку, если она существует. Убедитесь, что у вас есть:

using namespace std;

or:

using std::swap;

где-то.

person Adam    schedule 20.08.2008

Хм, у меня нет большого опыта работы с STL. Не могли бы вы привести пример?

Эта программа создает вектор целых чисел, сортирует его и отображает результаты.

#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

int main()
{
    vector<int>; vec;
    vec.push_back(7);
    vec.push_back(5);
    vec.push_back(13);
    sort(vec.begin(), vec.end());

    for (vector<int>::size_type i = 0; i < vec.size(); ++i)
    {
        cout << vec[i] << endl;
    }
}
person Brian Ensink    schedule 20.08.2008

Чтобы завершить пост Брайана Энсинка, вы найдете STL, полную сюрпризов. Например, алгоритм std::sort:

#include <iostream>
#include <vector>
#include <algorithm>

void printArray(const std::vector<int *> & p_aInt)
{
   for(std::vector<int *>::size_type i = 0, iMax = p_aInt.size(); i < iMax; ++i)
   {
      std::cout << "i[" << static_cast<int>(i) << "] = " << reinterpret_cast<unsigned     int>(p_aInt[i]) << std::endl ;
   }

   std::cout << std::endl ;
}


int main(int argc, char **argv)
{
   int a = 1 ;
   int b = 2 ;
   int c = 3 ;
   int d = 4 ;
   int e = 5 ;

   std::vector<int *> aInt ;

   // We fill the vector with variables in an unordered way
   aInt.push_back(&c) ;
   aInt.push_back(&b) ;
   aInt.push_back(&e) ;
   aInt.push_back(&d) ;
   aInt.push_back(&a) ;

   printArray(aInt) ; // We see the addresses are NOT ordered
   std::sort(aInt.begin(), aInt.end()) ; // DO THE SORTING
   printArray(aInt) ; // We see the addresses are ORDERED

   return EXIT_SUCCESS;
}

Первая печать массива покажет неупорядоченные адреса. Второй, после сортировки, покажет упорядоченные адреса. В моем компиляторе у нас есть:

i[0] = 3216087168
i[1] = 3216087172
i[2] = 3216087160
i[3] = 3216087164
i[4] = 3216087176

i[0] = 3216087160
i[1] = 3216087164
i[2] = 3216087168
i[3] = 3216087172
i[4] = 3216087176

Взгляните на заголовок алгоритма STL http://www.cplusplus.com/reference/algorithm/ Вы найдете множество утилит. Обратите внимание, что у вас есть другая реализация контейнеров, которая может подойти вам лучше (std::list? std::map?).

person paercebal    schedule 21.09.2008
comment
На самом деле он хочет отсортировать значение, на которое указывает. Вам нужно добавить лямбду в сортировку для разыменования указателей вместо сортировки указателей. Проверьте исходный пост. - person ceorron; 20.09.2020