【问题标题】:C: Sorting a list alphabeticallyC:按字母顺序对列表进行排序
【发布时间】:2014-02-08 07:01:45
【问题描述】:

我的项目有问题。我编写了一个函数,它从文件中读取结构,按字母顺序对其进行排序并写回文件。从文件中读取并将其放回原处是可以的,因为我在其他函数中使用相同的代码并且它运行完美。 我的排序有问题,因为使用此功能后 txt 文件为空白。 它正在处理函数之外的结构:

typedef struct baseofwords                                
    {
        char *word;
        char *category;
        struct baseofwords* next;
    } base;

这是我的功能:

void SORTING (base **head)
{
char word[30];
char category[20];
FILE *fp;
if ((fp = fopen("baza.txt", "r"))==NULL)
    {printf("Error while opening the file!");
    exit(EXIT_FAILURE);}
else
    {
    while(!feof(fp))
        {
        fscanf(fp,"%s %s \n", word, category);
        base *wsk = *head;
        base *new = malloc (sizeof(base));
        new -> next = NULL;
        new -> word = strdup(word);
        new -> category = strdup(category);
        if(wsk == NULL)
            {
            new -> next = *head;
            *head = new;
            }
        else
            {
            while(wsk -> next != NULL)
            wsk = wsk -> next;
            wsk -> next = new;
            }
        }
    }
fclose(fp);
//==========================================up until here it works, problem must be down there


base *newHead = NULL;
base *wsk1, *wsk2, *tmp;
wsk1 = tmp = *head;
wsk2 = NULL;
while(tmp->next)
    { if (tmp->next->word > wsk1->word)
        { wsk2 = tmp;
        wsk1 = tmp->next;
        }
    tmp = tmp->next;
    }
if (wsk2) wsk2->next = wsk1->next;
else *head = wsk1->next;
wsk1->next = newHead;
newHead = wsk1;
*head = newHead;


//======================this part is okay again
if ((fp = fopen("base.txt", "w"))==NULL)
    {printf("Error while opening file!");
    exit(EXIT_FAILURE);}
else
    {base *wsk = *head;
    while (wsk->next != NULL)
    {fprintf(fp, "%s %s\n", wsk->word, wsk->category);
    wsk=wsk->next;}
    }fclose(fp);
}

非常感谢您的帮助!

【问题讨论】:

  • 这一行如何:base *new = malloc (sizeof(baza)); ?我什至看不到它是如何编译的......
  • 对不起!我用我的语言翻译了它。它是基础 *new=malloc (sizeof(base)); ,当然!
  • 我认为如果我们查看您正在使用的实际代码会更好,或者甚至更好......如果您在发布之前编译并测试您在此处发布的代码说“它有效”...
  • 最好的调试方法是将打印语句放入循环中,告诉你 wsk1、temp 和 wsk2 每次都是什么。我认为这样你会很快找到错误,而不是等待我们中的一些热心人士推断你想要做什么......
  • 你错误地使用了feof:stackoverflow.com/questions/5431941/…

标签: c list sorting


【解决方案1】:

这里有几处是错误的,让我们看看这个循环:

while(tmp->next)
    { if (tmp->next->word > wsk1->word)
        { wsk2 = tmp;
        wsk1 = tmp->next;
        }
    tmp = tmp->next;
    }

您将某些东西分配给wsk2,然后从不使用它。您尝试通过比较其地址(而不是该地址的值)来比较 word。而且我根本看不到您如何重新订购商品。

要比较两个字符串,你需要使用strcmp,你还需要决定你想要它们的顺序。

其次,您不能仅通过单步执行一次列表来对列表进行排序。您将不得不使用嵌套循环来比较项目并执行可能的多次移动以将项目移动到位。

并且对链表中的项目进行重新排序(单个链接不少于)是相当困难的,并且充满了必须考虑的边缘条件。当您想要交换两个项目时,您应该考虑将指针移动到 wordcategory。这可能看起来像:

void swapbases( base *it1, base *it2 )
{
  base tmp= * it1 ;
  it1-> word= it2-> word, it1-> category= it2-> category ;
  it2-> word= tmp.word, it2-> category= tmp.category ;
}

然后编写几个循环遍历并找出乱序的项目。有一种可怕的叫冒泡排序:

int swaps ;
for ( swaps= 1 ; ( swaps ) ; )
{
  swaps= 0 ;
  for ( tmp= head ; ( tmp-> next ) ; tmp= tmp-> next )
  {
     if ( strcmp( tmp-> word, tmp-> next-> word ) < 0 )
       { swapbases( tmp, tmp-> next ) ;  swaps ++ ; }
  }
}

【讨论】:

  • 是的,看起来 while{} 之后的代码应该以某种方式在其中(因为这是使用 wsk2 的代码之后)
  • 非常感谢您耐心地向我解释一切!现在我看到了我的错误。我在一段时间后删除了该部分,并添加了您告诉我的内容。{}现在它可以正确保存列表,但它仍然未排序。
猜你喜欢
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
  • 2021-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多