Я делаю упражнение K&R 6-4, а именно:
6-4. Напишите программу, которая печатает на входе отдельные слова, отсортированные в порядке убывания частоты их появления. Предшествуйте каждому слову его количество.
Я решил создать структуру с именем dstncFreqNode6_4:
struct dstncFreqNode6_4
{
char *word;
int count;
struct dstncFreqNode6_4 *left;
struct dstncFreqNode6_4 *right;
};
Затем я проанализировал ввод на наличие слов и для каждого отдельного слова создал один узел "dstncFreqNode6_4" и два указателя на него: один для вставки в BST (для добавления новых слов/обновления количества уже встреченных слов) и один для вставить в глобальный массив указателей "dsntFredNode6_4".
Это было сделано для того, чтобы я мог обновлять количество слов (узлов) путем обхода BST (который содержит указатели на все встреченные до сих пор слова). После того, как весь ввод будет проанализирован, массив указателей будет отсортирован по переменным «количества» членов, а затем напечатан. Поскольку
Код добавления новых слов/обновления счетчиков находится здесь:(Я не думаю, что с этим что-то не так, так как BST и массив заполнены правильно, так что вы можете игнорировать это) :
//"wordCounts" is originally a global dstncFreqNode6_4** declared outside the function, numWords is the current length of the array
struct dstncFreqNode6_4 *addFreqNode6_4(struct dstncFreqNode6_4 *root, char *word)
{
if(root == NULL)
{
root = (struct dstncFreqNode6_4 *) malloc(sizeof(struct dstncFreqNode6_4));
root -> word = word;
root -> count = 1;
root -> left = NULL;
root -> right = NULL;
struct dstncFreqNode6_4 **p;
wordCounts = (struct dstncFreqNode6_4 **) realloc(wordCounts, sizeof(struct dstncFreqNode6_4*) * (numWords +1));
p = wordCounts + numWords++;
(*p) = root;
}
else if(strcmp(word, root -> word) < 0)
root -> left = addFreqNode6_4(root -> left, word);
else if(strcmp(word, root -> word) > 0)
root -> right = addFreqNode6_4(root -> right, word);
else
root -> count++;
return root;
}
Итак, у меня все работает правильно, кроме сортировки; он просто не будет сортировать массив. То есть... порядок элементов остается неизменным EDIT: я получаю ошибку сегментации. EDIT #2: Теперь ошибки сегментации нет; исходная проблема все еще существует.
Я использую метод qsort stlib.h; функция сравнения, которую я использую:
int qcmp6_4(const void *a, const void *b)
{
return (*(struct dstncFreqNode6_4 **)a) -> count - (*(struct dstncFreqNode6_4 **)b) -> count;
}
Я не могу понять, почему он не сортируется правильно. На самом деле я реализовал свой собственный алгоритм быстрой сортировки и получаю те же результаты. Я действительно не знаю на данный момент.
Было бы неплохо получить свежие и опытные взгляды, чтобы указать мне правильное направление. Спасибо.
ИЗМЕНИТЬ
Извините, вот вызов qsort:
qsort(wordCounts, numWords, sizeof(struct dstncFreqNode6_4 *), qcmp6_4);
РЕДАКТИРОВАНИЕ № 2:
Следуя предложению, я сделал "wordCounts" массив указателей на узлы (весь код в этом посте был обновлен, чтобы отразить это). Таким образом, по сути, BST и массив содержат одинаковую информацию (на самом деле указатели массива инициализируются соответствующим указателем в BST), но их использование различно. BST используется для добавления новых слов/обновления количества уже встреченных слов, а в конце массив сортируется (по количеству слов) и печатается. Однако я столкнулся с той же проблемой, с которой столкнулся изначально: порядок массива остается прежним после вызова qsort.