简体   繁体   English

Radix分类功能出现问题

[英]Trouble with a Radix sort function

In my program I am using a Radix Sort via Linked List to sort nine digit numbers, but for some reason it is not sorting correctly. 在我的程序中,我使用“通过链接列表进行基数排序”对九位数字进行排序,但是由于某种原因,它无法正确排序。

This is how I generate my numbers: 这是我生成数字的方式:

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);
}

This is the Radix Sort function: The outer loop is run through 3 times. 这是基数排序功能:外循环运行3次。 Once for each set of 3 digits. 每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 
}

I think that the problem might have to be with the new node that I create. 我认为问题可能出在我创建的新节点上。 What am I doing wrong? 我究竟做错了什么?

Your logic for storing a number in a linked list is not correct. 您在链接列表中存储数字的逻辑不正确。

Here is a suggested outline: 这是建议的轮廓:

  • Always create a new node to store the number. 始终创建一个新节点来存储号码。
  • Always set the next pointer of the new node to NULL . 始终将新节点的next指针设置为NULL
  • Find the end of the linked list at bucket[index] . bucket[index]处找到链表的末尾。

    • If there is no linked list at bucket[index] then you have already found the end. 如果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. } 

EDIT: You already had a while loop that follows the linked list from its head to its tail. 编辑:您已经有一个while循环,从头到尾跟随链表。

To get the values out of the linked list, you also start at the head and then follow the list until you reach the tail. 要从链接列表中获取值,您还可以从头开始,然后按照列表进行操作,直到到达末尾。 But, as you visit each node in the list, you get out a value. 但是,当您访问列表中的每个节点时,就会得到一个值。

            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;
            }

But we can make this cleaner with a do / while loop. 但是,我们可以使用do / while循环使此清洁器更清洁。 You use a do / while when you want to do something at least once, and possibly more than once. 当您想至少做一次,并且可能要做多次时,可以使用do / while In this case, if we run this loop at all it is because we want to get out at least one number. 在这种情况下,如果我们完全运行此循环,那是因为我们希望至少获得一个数字。 So: 所以:

            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);

It's cleaner to use a do / while loop, than to repeat the line that stores a value in out . 使用do / while循环比重复存储out的值的行更干净。

The loop can handle any length list other than length 0, and you already have the check with the continue to handle the case where there is no linked list in bucket[i] . 循环可以处理长度为0以外的任何长度列表,并且您已经可以continue进行检查以处理bucket[i]没有链接列表的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM