Предостережение: Поскольку кажется, что у вас все еще есть проблемы даже с ответом Влада, я придумала переработанную версию [которая может или не может быть тем, что вы хотели].
Я использую два списка. Добавьте необработанные входные строки в первый список, но просто увеличьте счетчик, если он дублирует существующую запись списка.
Итак, теперь у нас есть список, в котором есть один элемент для каждой уникальной строки и ее частота / количество повторений.
Затем переместите записи во второй список, отсортировав их по частоте.
Итак, вот код. Как я уже упоминал в моих комментариях, рекурсивное решение не масштабируется и, более того, медленнее. По крайней мере, это может помочь вам адаптировать вашу версию. YMMV ...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 16
typedef struct column column_t;
struct column {
column_t *next;
column_t *prev;
long rep;
char col3[MAX_SIZE];
};
column_t *
newnode(char *col3)
{
column_t *new = malloc(sizeof(column_t));
strcpy(new->col3,col3);
new->prev = NULL;
new->next = NULL;
new->rep = 1;
return new;
}
// addnode -- add string to basic list
column_t *
addnode(column_t *head,char *col3)
{
column_t *cur;
column_t *prev;
column_t *new;
do {
// add to empty list
if (head == NULL) {
new = newnode(col3);
head = new;
break;
}
// find matching node for string
prev = NULL;
for (cur = head; cur != NULL; cur = cur->next) {
if (strcmp(cur->col3,col3) == 0)
break;
prev = cur;
}
// increment count on existing node
if (cur != NULL) {
cur->rep += 1;
break;
}
// append to tail of list
new = newnode(col3);
prev->next = new;
new->prev = prev;
} while (0);
return head;
}
column_t *
sorted_insert(column_t *head,column_t *new)
{
column_t *cur;
column_t *prev;
do {
new->next = NULL;
new->prev = NULL;
// add to empty list
if (head == NULL) {
head = new;
break;
}
// find next higher node count
prev = NULL;
for (cur = head; cur != NULL; cur = cur->next) {
if (cur->rep > new->rep)
break;
prev = cur;
}
// insert before a node that is higher
if (cur != NULL) {
prev = cur->prev;
if (prev != NULL)
prev->next = new;
new->prev = prev;
new->next = cur;
// inserting before the head of the list
if (cur == head)
head = new;
break;
}
// new node is higher than all -- append to tail of list
new->prev = prev;
if (prev != NULL)
prev->next = new;
} while (0);
return head;
}
void
listprint(column_t *head,const char *tag)
{
column_t *cur;
for (cur = head; cur != NULL; cur = cur->next)
printf("%s %s - %ld\n",tag,cur->col3,cur->rep);
}
int
main(void)
{
column_t *orig = NULL;
char *input[] = {
"DA", "DA",
"JL",
"FF",
"JD",
"FF",
"PQ", "QP",
"QP", "QP", "QP",
NULL
};
for (char **str = input; *str != NULL; ++str)
orig = addnode(orig,*str);
listprint(orig,"ORIG");
column_t *sorted = NULL;
column_t *next;
for (; orig != NULL; orig = next) {
next = orig->next;
sorted = sorted_insert(sorted,orig);
}
listprint(sorted,"SORT");
return 0;
}