简体   繁体   English

双链表实现

[英]doubly linked list implementation

Which one would be more efficient? 哪一个效率更高?

I want to keep a list of items but, it's required of me to sort list 我想保留一个项目列表,但是我需要对列表进行排序

  • by id, 根据ID,
  • by name 按名字
  • by course credits 按课程学分
  • by the user 由用户

Would it be best to add items in list by id and then sort by the others or just add items without order and sort in the order needed when ever needed by the user? 最好按ID在列表中添加项目,然后按其他项目排序,还是仅按顺序添加项目,而无需在用户需要时按所需的顺序排序?

If you're really required to keep the list sorted -- as opposed to using other data structures to give sorted access to the list -- then you could simply make a list whose elements have different pointers for different sort criteria. 如果确实需要对列表进行排序(而不是使用其他数据结构来对列表进行排序访问),则可以简单地创建一个列表,其元素针对不同的排序标准具有不同的指针。

In other words, instead of keeping just previous and next pointers, have previousById , nextById , previousByName , previousByCredits and nextByCredits . 换句话说,不是仅保留上previousnext指针,而是要具有previousByIdnextByIdpreviousByNamepreviousByCreditsnextByCredits Likewise, you would have three head and/or tail pointers, instead of just one. 同样,您将拥有三个头和/或尾指针,而不仅仅是一个。

Please note that this approach has the drawback of being inflexible when it comes to implementing additional sort criteria. 请注意,这种方法的缺点是在实现其他排序标准时不灵活。 I'm assuming that you're trying to solve a homework-type problem, which is why I tried to tailor the answer to what seem to be the homework requirements. 我假设您正在尝试解决作业类型的问题,这就是为什么我尝试针对似乎是作业要求的问题量身定制答案的原因。

您可以使用三种映射(或哈希映射):一种将ID映射到项目,一种将名称映射到项目引用(或指针),另一种将课程学分映射到项目引用。

It would be more efficient to sort it in whichever order that you know will be sorted for the most, for example if you know you're going to be retrieving by id most often, keep it sorted by id , otherwise pick one of the others though id would be the easiest if it is just an integer field 按您知道的排序顺序最高的顺序进行排序会更有效,例如,如果您知道您将最常按id进行检索,请按id对其进行排序,否则请选择其中一个如果id只是一个整数字段,则id是最简单的

So then to do that you would check on insert to find where newid is less than nextid but greater than previousid , then allocate a new node with new and set the pointers appropriately. 那么接下来要做到这一点,你会检查插入发现其中newid小于nextid但大于previousid ,然后分配一个新的节点new和设置适当的指针。

Keeping the linked list sorted in some way is better than just keeping it unsorted. 以某种方式对链表进行排序要比不对链表进行排序更好。 You're adding some time to how long it takes to insert an item but it's negligible to how long it would take to sort it that particular way 您在插入项目所需的时间上增加了一些时间,但是以某种特定方式对其进行排序所需的时间可以忽略不计

The more efficient would be to store the nodes as is, and keep 4 different indexes up-to-date. 更有效率的是按原样存储节点,并保持4个不同的索引为最新。 This way, when one order is required, you just pick up the right index and that's all. 这样,当需要一个订单时,您只需要选择正确的索引即可。 The cost is O(log N) for input, and O(1) for traversal. 输入的成本为O(log N),遍历的成本为O(1)。

Of course, keeping 4 indexes at once, with perhaps different requirements on uniqueness, and in the face of possible exceptions, is relatively difficult, but then, there's a Boost library for this: Boost MultiIndex 当然,要同时保持4个索引(对唯一性的要求可能不同,并且面对可能的异常)是相对困难的,但是,这里有一个Boost库: Boost MultiIndex

On example is to generate a set that can be sorted either by ID or by Name . 例如,生成一个可以按ID或Name排序的集合。

Since you can add as many indexes as you wish, it should get you going :) 由于您可以根据需要添加任意数量的索引,因此应该可以进行:)

Keep your lined list objects in the lined list, in random order. 将衬里列表对象以随机顺序保留在衬里列表中。 To sort the list by any key, use this pseudocode: 要使用任何键对列表进行排序,请使用以下伪代码:

struct LinkedList {
    string name;
    LinkedList *prev;
    LinkedList *next;
};

void FillArray(LinkedList *first, LinkedList **output, size_t &size) {
    //function creates an array of pointers to every LinkedList object
    LinedList *now;
    size_t i; //you may use int instead of size_t

    //check, how many objects are there in linked list
    now=first;
    while(now!=NULL) {
        size++;
        now=now->next;
    }

    //if linked list is empty
    if (size==0) {
        *output=NULL;
        return;
    }

    //create the array;
    *output = new LinkedList[size];

    //fill the array
    i=0;
    now=first;
    while(now!=NULL) {
        *output[i++]=now;
        now=now->next;
    }
}

SortByName(LinkedList *arrayOfPointers, size_t size) {
    // your function to sort by name here
}

void TemporatorySort(LinkedList *first, LinkedList **output, size_t &size) {
    // this function will create the array of pointer to your linked list,
    // sort this array, and return the sorted array. However, the linked
    // list will stay as it is. It's good for example when your lined list
    // is sorted by ID, but you need to print it sorted by names only once.
    FillArray(first, *output, size);
    SortByName(output,size);
}

void PermanentSort(LinkedList *first) {
    // This function will sort the linked list and save the new order
    // permanently.
    LinkedList *sorted;
    size_t size;
    TemporatorySort(first,&sorted,size);
    if (size>0) {
        sorted[0].prev=NULL;
    }
    for(int i=1;i<size;i++) {
        sorted[i-1].next=sorted[i];
        sorted[i].prev=sorted[i-1];
    }
    sorted[size-1].next=NULL;
}

I hope, I actually did help you. 希望我确实对您有所帮助。 If you don't understand any line from the code, simply put a comment to this "answer". 如果您不理解代码中的任何一行,只需在此“答案”中添加注释。

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

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