【问题标题】:efficiency of linked list sorting code c++ [closed]链表排序代码c ++的效率[关闭]
【发布时间】:2015-02-22 13:18:38
【问题描述】:

我编写了一个代码,它按排序顺序将新的随机数添加到链表中。看起来它工作正常,但与我看到的不同。

你能不能从内存消耗的角度看一下,说效率好不好?

我还听说如果使用指向当前数字位置的指针(指向位置指针的指针)对列表进行排序,那么它会 成为最有效的算法。是这样吗?

void add (num*&head, int size) {

    num*temp = head;
    num*prev = 0;
    num*first = head;

    int n;
    int min = 0;
    for (int i = 0; i<size; i++){
    num*node = new num;
    node->n = rand()%100;
    cout << node->n << endl;

    if (head!=0) {
        if (prev != 0) {
            if (node->n < head->n){
                if (node->n < first->n) {
                    node->next = 0;
                    first->next = node;
                    first = node;
                }
                else { 
                temp = head;
                while (temp->next != 0)
                {
                    if (node->n <= temp->n && node->n >= temp->next->n) {
                        node->next = temp->next;
                        temp->next = node;
                        temp = head;
                        break;
                    }
                    else {
                        temp = temp->next;
                    }}}}
            else 
            {
                node->next = head;
                head = node;
                temp = head;
            }}
        else {
            if (node->n < temp->n){

                node->next = 0;
                temp->next = node;
                prev = node;
                first = prev;
            }
            else { 
                node->next = head;
                head = node;
                prev = node->next;
                first = prev;
            }}}
    else {
    node->next = head;
    head = node;
    temp = head;
    first = head;
    }}}

【问题讨论】:

  • 高效究竟是什么意思?占用空间、性能、内存消耗?
  • 是的,感谢您的评论 - 内存消耗
  • 为了节省时间,让我们用文字来描述你的算法:你有一个排序列表,并定义了操作 insert(x),它为新元素 x 找到正确的位置(从开始的 intil它找到了正确的位置)并把它放在那里,是这样吗?

标签: c++ list sorting


【解决方案1】:

如果您的算法遵循 MDo 评论中概述的算法,则可以通过更少的比较来搜索正确的位置(通过使用比仅一个元素更大的步长并在您进入时减小步长)。但是,当使用链表时,这不会使您的代码更快,因为列表的遍历仍然需要访问每个单个元素,直到找到正确的位置(到目前为止,平均所有元素的一半)。这将产生与您更简单的算法相同数量的缓存未命中(这是 效率杀手)。因此,在添加随机元素的同时保持链表排序不能高效地完成

可以高效完成的事情是将列表保存在 heap orderadding random elements 中(每个成本为 O(log N))。最后,在添加完所有元素后,直接从堆顺序中快速obtain a sorted order

实际上,堆排序算法是这样工作的:首先将一个随机顺序排列成堆顺序,然后得到一个排序后的顺序(平均效率比快速排序稍差)。

【讨论】:

  • 实际上,它的工作方式如下:添加前两个元素后,将它们排序。然后程序将新元素与“头”和“尾”进行比较。如果我们的新元素在它们之间的某个地方,那么代码会尝试找到两个数字,这样新元素就在它们之间。但是,感谢您对算法的评论
  • @VVG 遵循我提出的想法,只是进行了小幅优化,总的来说,这并没有什么不同
【解决方案2】:

这个算法实际上是插入排序(有一个小的优化,通过查找最后排序的元素)。

可以实现消耗更少的内存。您可以使用一些内存来维护列表 - 指向下一个元素的指针、指向尾部的指针等。 您实际上并不需要它,因为一个简单的数组可以提供相同的功能,但消耗的内存更少。

@Walter 已经提到堆,但还有其他现代排序算法,如 块排序,它们都是原地稳定的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-18
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 2012-02-10
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    相关资源
    最近更新 更多