繁体   English   中英

在C ++中对整数的链表进行排序

[英]Sorting a linked-list of ints in C++

我必须创建一种从最小到最大顺序存储整数的链接列表。 如果您具有或知道如何对链表进行排序,请在此处显示是否关闭和/或教我如何使用C ++进行编码。

我经常通过索引指针列表对链接列表进行排序。 要构建一个,需要的内存分配等于节点数(N)*节点指针的大小。 这个概念很简单。

注:该算法是C,因为我不能完全肯定是否意味着这个类作为一个C ++的问题( 到底谁在使用您的处置??链接在C列出++与标准集装箱)的OP

  1. 确定列表中的节点数(N)
  2. 为N个节点指针分配一个指针数组。
  3. 使用列表中的每个节点指针加载指针数组。 即遍历列表,然后将指针放在指针数组的每个插槽中,并随您的增加而递增。
  4. 将此节点指针数组发送到您的排序算法(我喜欢运行时库qsort()因为它是标准配备的)。
  5. 排序后,遍历整个指针数组(少一个),将每个节点的“下一个”指针设置为指向后面的指针。 最后一个将其“下一个”指针设置为NULL。
  6. 将头指针设置为指针数组中的第一个指针[0]。
  7. 释放指针数组的内存

您的链接列表已排序。


假设您的节点是这样的:

struct node
{
   ..data fields..
   int keyField;  // << determines sort order
   struct node *next;
};

确定列表中的节点数。 我假设您有一个可以执行此操作的proc,这很简单:

size_t list_count(struct node* head)
{
   size_t count = 0;
   while (head)
   {
      ++count;
      head = head->next;
   }
   return count;
}

分配一个列表大小的指针数组,其中nItems是列表节点计数大于1的列表(烦扰长度为零或一的列表是没有意义的):

struct node **ptrs = malloc(sizeof(*ptrs)*nItems);

用列表中的所有项目填充指针数组:

struct node *ptr = head;
size_t i=0;
for (;i<nItems;++i,ptr = ptr->next)
    ptrs[i] = ptr;

现在,使用适当的比较函数将其发送到qsort() 下面是一个根据我们结构中的keyField进行排序的比较函数示例:

int compare_node_ptrs(const void* left, const void* right)
{
    struct node *l = *(struct node**)left;
    struct node *r = *(struct node**)right;
    return l->keyField - r->keyField;
}

调用qsort()如下所示:

qsort(ptrs, nItems, sizeof(*ptrs), compare_node_ptrs);

现在遍历整个列表。 重新连接“下一个”指针:

for (i=0;i<(nItems-2);++i)
    ptrs[i]->next = ptrs[i+1];
ptrs[nItems-1] = NULL;

重新连接头指针。

head = ptrs[0];

最后,释放指针数组。

free(ptrs);

您的链接列表已排序。


边栏合并排序是我所知道的唯一O(nlogn)算法,可以对链表进行排序,而无需增加空间。 可以原型为以下内容的通用解决方案是nutz:

mergesort_list(void **head, size_t offset_ptr, int(*comp)(void*,void*))

head: address of the head pointer.
offset_ptr: offset in bytes from a node ptr where the 'link' pointer can be found.
comp: comparison function.

如果仅向您显示代码,我们将对您造成极大的伤害。 相反,我将为您提供两种不同的方法,您可以实施自己喜欢的一种方法。

第一种方法是在插入时进行“排序”:在插入值(例如7)时,请按照以下过程从列表中的第一个条目开始,直到用尽节点:

如果要检查的节点的值大于7,则在要检查的节点之前插入一个新节点并返回。 否则,您将查看下一个节点。 如果没有下一个节点,则。 您在列表末尾插入一个新节点,因为这意味着7比列表中的其他条目大,然后返回。

第二种选择是使用许多排序算法之一对整个列表进行排序。 我建议您使用BubbleSort,因为它易于理解和实施。 您可以在Wikipedia上阅读有关Bubblesort(其他许多排序算法)的更多信息。

好的旧的quicksort可以解决问题(C ++ 03友好):

#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>

using namespace std;

void qsort(list<int>::iterator first, list<int>::iterator last)
{
    if (distance(first, last) < 2)
        return;
    int pivot = *first;

    list<int>::iterator it = partition(first, last, bind2nd(less<int>(), pivot));

    qsort(first, it);
    qsort(it, last);
}

int main()
{
    std::list<int> l;
    l.push_back(5);
    l.push_back(4);
    l.push_back(1);
    l.push_back(10);
    l.push_back(3);
    l.push_back(6);
    l.push_back(7);

    cout << "List:";
    copy(l.begin(), l.end(), std::ostream_iterator<int>(std::cout, " "));
    cout << endl;

    qsort(l.begin(), l.end());

    cout << "Sorted list:";
    copy(l.begin(), l.end(), std::ostream_iterator<int>(std::cout, " "));
    cout << endl;
    return 0;
}

检查: http//ideone.com/OOGXSp

暂无
暂无

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

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