维护已排序的链接列表

时间:2010-07-23 00:35:12

标签: c++ linked-list

我正在尝试创建和维护已排序的链接列表。应以列表保持排序的方式插入每个新元素。我已经能够对它进行编码,但对我的代码不太满意。

基本上,根据我需要满足4个条件,并且在我尝试实现所有这些条件时,我认为我已经使代码变得更加复杂。

只是想知道是否有人更有效地编码它,如果你能告诉我如何在这里改进插入功能。这是我下面的工作代码和评论中的条件。为了保持小,我没有发布删除元素,销毁列表等的函数。

#include <iostream>

    using namespace std;

    struct node{
        int _val;
        node* _next;
    };

    void printList(node **s){

        node *t = *s;
        while(t){
            cout << t->_val << endl;
            t = t->_next;
        }
    }

    void insertSortElement(node** s, int val){

        node* t = *s;
        if(t){
            if(t->_next == NULL || (t->_val > val)){
                node* p = new node();
                p->_val = val;
                if(t->_val > val){
                    //3. More than 1 element in the list but 1st element > val
                    p->_next = t;
                    *s = p;
                }
                else{
                    //2. Only 1 element in the list and < val
                    t->_next = p;
                }
            }
            else{
                //4. More than 1 element and 1st < val
                node* prev = 0;
                while(t){
                    if(t->_val > val)
                        break;
                    prev = t;
                    t = t->_next;
                }
                node* p = new node();
                p->_val = val;
                p->_next = t;
                prev->_next = p;
            }
        }
        else{

            //1. no element in the list
            node* p = new node();
            p->_val = val;
            p->_next = NULL;
            *s = p;
        }
    } 

    int main(){
        struct node* s = 0 ;

        insertSortElement(&s,5);
        insertSortElement(&s,6);
        insertSortElement(&s,4);
        insertSortElement(&s,2);
        insertSortElement(&s,8);
        insertSortElement(&s,1);
        printList(&s);
    }

编辑:

找到另一个实现,比我的更简单并处理所有情况

void insertSorted(node**s , int val){
        node* current = *s;

                if(current == NULL || current->_val >= val){
                        node* p = new node();
                        p->_val = val;
                        p->_next = current;
                        *s = p;
                }
                else{

                        while(current->_next != NULL || current->_next->_val < val)
                                current = current->_next;

                        node*  p = new node();
                        p->_val = val;
                        p->_next = current->_next;
                        current->_next = p;
                }
}

3 个答案:

答案 0 :(得分:2)

更快的方法是使用二进制搜索来找到要插入的正确位置。它被称为“跳过列表”。

此外,您可以使用santinels来避免检查第一个和最后一个元素的特殊情况。

答案 1 :(得分:1)

我认为你应该编写一个方法insertElement,然后将insertSortedElement重写为“搜索要插入的位置,然后只调用insertElement” - 我认为这会清理代码并使其更具逻辑性和可读性。

这样,您可以编写更多模块化代码。所有奇怪的边缘情况都可以通过insertElement来处理,你可以单独优化插入和位置搜索,这将导致更少的混淆。

一些伪代码:

insertElement(node old_node, value val)
  allocate memory for new node new_node
  new_node.val = val
  new_node.next = old_node
  new_node.prev = old_node.prev

insertSortedElement(value val)
  actnode = first node
  while actnode.next != NULL
    if (actnode.val >= val)
      insertElement(actnode, val)
      break;
    actnode = actnode.next

应该那么简单,希望我没有忘记任何事情......

答案 2 :(得分:0)

呃...为什么?这不是std::multiset的用途吗?

#include <set> //for std::multiset
#include <iterator> //for std::ostream_iterator
#include <algorithm> //for std::copy
#include <iostream> //for std::cout

int main()
{
    //Put things in sorted collection.
    std::multiset<int> collection;
    collection.insert(5);
    collection.insert(6);
    collection.insert(4);
    collection.insert(2);
    collection.insert(8);
    collection.insert(1);

    //Print them to show sort.
    std::copy(collection.begin(), collection.end(), std::ostream_iterator(std::cout, "\n"));
}