【问题标题】:Trouble with a Radix sort function基数排序功能的问题
【发布时间】:2013-10-17 01:42:21
【问题描述】:

在我的程序中,我使用基于链表的基数排序来对九位数字进行排序,但由于某种原因,它没有正确排序。

这就是我生成数字的方式:

void genData(int *dta, int n) 
{
    // generate the numbers at random
    for(int i=0; i < n; i++)
        dta[i] =  rand()%889 + 111 + 1000*(rand()%889 + 111) + 1000000*(rand()%889 + 111);
}

这是基数排序函数: 外循环运行 3 次。每组 3 位数字一次。

int radixSort(int *dta, int n, int *out)
{ 
    // the dta array contains the data to be sorted.
    // n is the number of data items in the array
    // out is the array to put the sorted data

    node *bucket[1000]; 
    int count = 0; 
    for(int i = 0; i < n; i++)out[i] = dta[i]; 

    for (int pass = 0; pass < 3; pass++)  // outer loop
    {
        for(int j = 0; j < 1000; j++) // set bucket[] to all zeroes (NULL) for each pass 
        {
            bucket[j] = NULL;
        }

        for(int i = 0; i < n; i++) // inner loop -- walks through the out array (which contains the data to be sorted)
        {
            int index = 0; 
            int tmp = 0;
            switch(pass) 
            {
                case 0:
                    index = out[i] % 1000;
                    break;
                case 1:
                    tmp = out[i]/1000; // tmp = 123456
                    index = tmp%1000; // mid = 456// set index to the middle 3 digits
                    break;
                case 2:
                    tmp = out[i]/1000;  // set index to the first 3 digits
                    index = tmp/1000;
                    break;
            };

            //Create new head node if nothing is stored in location
            if(bucket[index] == NULL)           
            {   
                node *newNode = new node(0, bucket[0]); 
            }
            else
            {
                node *newNode =  new node(out[i], NULL); //Created new node, stores out[i] in it
                node *temp = bucket[index];
                while(temp->next != NULL) // finds the tail of the Linked List
                {
                    temp = temp->next;
                    count++; //For Big-O
                }
                temp->next = newNode;   // make tail point to the new node.
            }
            count++; //For Big-O
        } // end of the inner (i) loop

        int idx = 0; // for loading the out array
        for(int i = 0; i < 1000; i++)  // walk through the bucket
        {
            if(bucket[i] == NULL)continue; // nothing was stored here so skip to the next item

            // something is stored here, so it is put into the out array starting at the beginning (idx)
            out[idx++] = bucket[i]->data;

            if(bucket[i]->next->next != NULL || bucket[i]->next->next)
            // now see if there are more nodes in the linked list that starts at bucket[i]. If there are, put their data into out[idx++]
            {
                out[idx++] = bucket[i]->data;
            }
            count++; //For Big-O
        }


    }// end of the outer loop pass). The output (out) from this pass becomes the input for the next pass

    return count; // Again -- for Big-O 
}

我认为问题可能出在我创建的新节点上。我做错了什么?

【问题讨论】:

  • 看起来你在第一次初始化时忘记设置bucket[index] = newNode;
  • 我会在创建 newNode 后立即这样做吗?
  • 是的,看看下面的答案,有道理

标签: c++ sorting linked-list


【解决方案1】:

您在链表中存储数字的逻辑不正确。

这是一个建议的大纲:

  • 始终创建一个新节点来存储号码。
  • 始终将新节点的next 指针设置为NULL
  • bucket[index]处找到链表的结尾。

    • 如果bucket[index]处没有链表,那么你已经找到了终点。

      node *newNode = new node(out[i], NULL);
      if (bucket[index] == NULL)           
      {
          // there was no linked list there before; start one now.
          bucket[index] = newNode; 
      }
      else
      {
          // find tail of linked list and append newNode
          node *temp = bucket[index];
          while (temp->next != NULL)
          {
              temp = temp->next;
              count++; //For Big-O
          }
          temp->next = newNode;   // make tail point to the new node.
      }
      

编辑:您已经有一个 while 循环,它从头到尾跟随链表。

要从链表中取出值,您也可以从头部开始,然后沿着链表直到到达尾部。但是,当您访问列表中的每个节点时,您会得到一个值。

            if (bucket[i] == NULL)continue; // nothing was stored here so skip to the next item

            // if we reach this point there is at least one value stored here

            // get values out
            node *temp = bucket[i];
            out[idx++] = temp->data;
            while (temp->next != NULL)
            {
                temp = temp->next;
                out[idx++] = temp->data;
            }

但是我们可以使用 do / while 循环来使这个更干净。当您想要做某事至少一次并且可能不止一次时,您可以使用do / while。在这种情况下,如果我们完全运行这个循环,那是因为我们想得到至少一个数字。所以:

            if (bucket[i] == NULL)continue; // nothing was stored here so skip to the next item

            // if we reach this point there is at least one value stored here

            // get values out
            node *temp = bucket[i];
            do
            {
                out[idx++] = temp->data;
                temp = temp->next;
            }
            while (temp != NULL);

使用do / while 循环比重复在out 中存储值的行更简洁。

循环可以处理长度为 0 以外的任何长度列表,并且您已经通过 continue 进行检查以处理 bucket[i] 中没有链表的情况。

【讨论】:

  • 随着它的改变,它似乎为我检查链表中以bucket[i] 开始的其他节点的行创建了一个Access Violation(运行时错误)。 if(bucket[i]-&gt;next-&gt;next != NULL || bucket[i]-&gt;next-&gt;next)。知道为什么现在会这样吗?
  • 表达式bucket[i]-&gt;next-&gt;next在链表长度为0或长度为1时会报错。如果bucket[i]NULL则会报错。如果bucket[i]-&gt;nullNULL 你也会得到一个错误。将-&gt; 运算符应用于NULL 指针总是错误的。
  • 您应该使用while 循环来跟踪链接列表中的条目。您现在使用 -&gt;next-&gt;next 的代码不正确。
  • 我猜是因为我不太明白如何检查与bucket[i]相同位置的其他节点
  • 所以使用while 循环,但我该如何检查呢? ^
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
  • 2015-05-27
  • 2011-05-16
  • 1970-01-01
  • 1970-01-01
  • 2013-10-22
相关资源
最近更新 更多