简体   繁体   English

排序双链表C ++

[英]Sorting a Doubly Linked List C++

Trying to do it through a loop that traverses through the list. 尝试通过遍历列表的循环来实现。

In the loop I'm feeding the head node into a sorting function that I have defined and then I'm using strcmp to find out if which name in the node should come first. 在循环中,我将头节点输入到已定义的排序函数中,然后使用strcmp来确定节点中的哪个名称应优先出现。

It is not working because writing the names too early. 它不起作用,因为过早写入名称。

Im comparing them all linearly by going down the list one node at a time and not going back to see if the first should come before the last. 我通过一次向下列出一个节点,而不回头看看第一个节点是否应该在最后一个节点之前,对它们进行线性比较。 That part explained would be helpful. 解释的那部分会有所帮助。

The two functions that are most important to me now are defined as follows: I have tried my best to do what I think is right for the sorting function. 现在,对我来说最重要的两个功能定义如下:我已尽力去做我认为适合排序功能的事情。

void list::displayByName(ostream& out) const
{
    list *ListPtr = NULL;
    node *current_node = headByName;
    winery *wine_t = new winery(); 
    // winery is another class object type
    // im allocating it to prevent a crash when I call it.

    while ( current_node != NULL )
    {
        *(wine_t) = current_node->item;
        wine_t = ListPtr->sort( current_node );
        out << wine_t << endl;
        current_node = current_node->nextByName;
    }
    delete wine_t;
}

winery * const list::sort( node * current_node ) const
{
    // current_node is the first node.
    const char *SecondName = NULL, *FirstName  = NULL;
    winery *wine_t   = new winery();

    if ( current_node != NULL )
    {
        SecondName   = current_node->item.getName();            
        current_node = current_node->nextByName;
        FirstName    = current_node->item.getName();
    }

    if ( strcmp( FirstName, SecondName ) == -1 )
    {
        *(wine_t)  = current_node->item;
        FirstName  = NULL;
        SecondName = NULL;
        return wine_t;
    }
    else if ( strcmp( FirstName, SecondName ) == 1 )
    {
        *(wine_t) = current_node->item;
        FirstName = NULL;
        SecondName = NULL;
        return wine_t;
    }
    else return wine_t;// then the strings are equal

    FirstName  = NULL;
    SecondName = NULL;
    return wine_t;
}

And I started to develop my nodes here: 我开始在这里开发节点:

void list::insert(const winery& winery)
{
    node *current_node = new node( winery );

    if ( headByName == NULL )
    {
        headByName   = current_node;
        headByRating = current_node;
        tail         = headByName;
        current_node->prev = current_node;
    }
    else
    {
        current_node->prev = tail;
        tail->nextByName   = current_node;
    }

    tail = current_node;
    current_node = NULL;
}

I think its correct in that function above. 我认为在上述功能中它是正确的。 Could I possibly get away with sorting it there? 我可以在那里整理一下吗?

Below are my varaibles that I am working with: 以下是我正在使用的变量:

public list
{
         ...
    void insert(const winery& winery);
    void displayByName(ostream& out) const;
}
private:
    struct node
    {
        node(const winery& winery);     // constructor
        winery item;
        node * prev;
        node * nextByName;
        node * nextByRating;
    };

    winery * const sort(node*) const;
    node * headByName;
    node * headByRating;
    node * tail;
};

Any help is appreciated. 任何帮助表示赞赏。 Thanks very much =) 非常感谢=)

Before I even get to the question asked, I observe some problems you probably want to address: 在我提出问题之前,我就注意到了您可能要解决的一些问题:

  • Your nodes have two different kinds of next 's, but only one kind of prev . 您的节点具有两种不同的next ,但是只有一种prev Is that really what you want, and if so, which next is paired with the prev ? 真的是你想要的东西,如果是这样,其next与配对prev
  • The method you have named sort doesn't sort , but acts as a comparison. 您命名为sort的方法不是sort ,而是作为比较。
  • You don't appear to have implemented an actual sort (or at least you haven't exhibited it here). 您似乎没有实现实际的排序(或者至少您没有在这里展示过)。
  • There is no need for the repetitive setting of FirstName and SecondName back to NULL in sort . 无需将sortFirstNameSecondName重复设置回NULL They are local variables and simple disappear when the method returns. 它们是局部变量,在方法返回时简单消失。
  • There is no need to do two strcmp 's in sort . 无需进行两个strcmpsort Either cache the result of the first one ( int cmp=strcmp(...); ) or use a switch on the value returned by strcmp`. 缓存第一个结果(int cmp = strcmp(...); ) or use a strcmp` on the value returned by ) or use a开关。

To sort a double linked array I would I would suggest one of: 为了对双链接数组进行排序,我建议以下之一:

  1. Using a standard container that supports std::sort if this is allowed (but I'm guessing that this is homework, so probably not). 如果允许的话,使用支持std::sort的标准容器(但是我猜测这是家庭作业,所以可能不行)。 I believe that std::list qualifies. 我相信std::list合格的。
  2. Sorting at insertion time if the sort order will never change 如果排序顺序永远不变,则在插入时进行排序
  3. Implementing a partition sort (ie quicksort ), which will work very nicely on this kind of structure (but the usual example code is given on arrays, so you will have to understand what is being done and why before the right way to implement it on linked lists becomes apparent). 实现一个分区排序(即quicksort ),它将在这种结构上很好地工作(但是通常的示例代码是在数组上给出的,因此您必须先了解正在执行的操作以及执行该操作的正确方法之前, 为什么要这样做)链表变得显而易见)。

Why isn't using std::list (the STL's doubly-linked list) and its associated sort function appropriate here? 为什么这里不使用std :: list(STL的双向链接列表)及其关联的排序功能呢? If you defined an operator< for your list items, it will Just Work and you won't have to write a whole bunch of code just to have a list and sort it. 如果您为列表项定义了一个operator <,它将可以正常工作,而您不必编写一堆代码就可以拥有一个列表并对其进行排序。

I wouldn't bother to write my own sort function. 我不会费心编写自己的排序函数。 I'd just use qsort . 我只用qsort Since it's interface is c and not c++, to use it you just build an array of object pointers, then call qsort on it with your own comparator function. 因为它的接口是c而不是c ++,所以要使用它,您只需构建一个对象指针数组,然后使用您自己的比较器函数对其调用qsort。 Then rebuild the linked list from the newly sorted array of object pointers. 然后从新排序的对象指针数组重建链接列表。

From what I understand, you want list::sort to find the least node in the list which is greater than the input. 据我了解,您希望list::sortlist::sort中找到大于输入的最小节点。

To do this, you need to iterate through all the elements and keep the current least-but-greater node found. 为此,您需要遍历所有元素,并保持找到当前最小但更大的节点。

Something like this: 像这样:

node * const list::sort( node * given_node ) const
{
    if ( given_node == NULL )
    {
        return NULL;
    }

    // Smallest node found which is greater than given_node.
    node * least_found_node = NULL;

    // Node we are looking at right now.
    node * current_node = given_node->nextByName;

    // Go through all nodes.
    while ( current_node && current_node != given_node )
    {
        // Is this node bigger than the given node?
        if ( strcmp( current_node->item.getName(), given_node->item.getName() ) < 0 )
        {
            // Is this node smaller than the smallest node we know of?
            if ( least_found_node == NULL ||
               ((strcmp( current_node->item.getName(), least_found_node->item.getName() ) > 0) )
            {
                // We found a better node.
                least_found_node = current_node;
            }
        }

        current_node = current_node->nextByName;
    }

    return least_found_node;
}

Now change your display function to use it like this: 现在,更改显示功能以使用它,如下所示:

void list::displayByName(ostream& out) const
{
    // Find first node initially.
    node * current_node = sort( NULL );

    while ( current_node != NULL )
    {
        // Print node.
        out << current_node->item.getName();

        // Find next node in sorted output.
        current_node = sort( current_node );
    }
}

This part keeps calling sort until sort returns NULL . 这部分将继续调用sort直到sort返回NULL为止。 The first call to sort is with NULL so the lowest item is found (that is, the first in the sorted list). sort的第一个调用是NULL因此找到了最低的项目(即排序列表中的第一个)。 sort returns NULL if there are no more nodes larger than current_node , thus terminating the loop. 如果没有更多的节点大于current_node ,则sort返回NULL ,从而终止循环。

如果您正在寻找一种有效的链表就地排序算法,请查看列表……我发现它非常快。

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

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