如何在双向链表 C++ 上使用插入排序?

Posted

技术标签:

【中文标题】如何在双向链表 C++ 上使用插入排序?【英文标题】:How to use insertion sort on doubly linked list C++? 【发布时间】:2017-10-25 04:08:56 【问题描述】:

我正在做一个项目,该项目需要我使用插入排序以最有效的方式对链表进行排序。我写了一个有效的算法,但它不是最有效的——它比较列表开头的值,而不是倒退。现在,我有一个算法可以比较向后的值,但它不起作用。调试器显示 current->prev 是一个 nullptr,因此它不会运行该函数。我已经对其进行了初始化,当我执行 cout prev 时,它会打印该值。我查看了有关此主题的其他帖子,但找不到我的代码行有什么问题。这是包含链表类中的函数的头文件:

#include<iostream>

class LinkedList

private:
struct ListNode

    double value;
    ListNode *next;
    ListNode *prev;
    ListNode(double val, ListNode* nextPtr = nullptr, ListNode* prevPtr = 
nullptr) :
        value(val), next(nextPtr), prev(prevPtr) 
;
ListNode *head;

public:
LinkedList()
 
    head = nullptr; 


~LinkedList() 

    while (head != nullptr)
    
        ListNode *current = head;
        head = head->next;
        delete current;
    

void insert(double val)

    if (!head)
        head = new ListNode(val);
    else
    
        ListNode *temp = new ListNode(val);
        temp->next = head;
        head->prev = temp;
        head = temp;
    


void display()

    ListNode *temp = head;
    while (temp != nullptr)
    
    std::cout << temp->value << " ";
    temp = temp->next;
    
    std::cout << std::endl << std::endl;


void insertSort()

    ListNode *marker, *current;

    for (marker = head->next; marker != nullptr; marker = marker->next)
    
        double temp = marker->value;                                 
        current = marker;   

        // this line throws the exception: read access violation.
        // current->prev was nullptr.                                       
        while (current != nullptr && current->prev->value >= temp) 
        
            current->value = current->prev->value;            
            current = current->prev;                       
        
        current->value = temp;                  
        
   
;

这里是源文件:

#include<iostream>
#include"Header.h"
using namespace std;

int main()

   LinkedList list;

   list.insert(23);
   list.insert(54);
   list.insert(2);
   list.insert(8);
   list.insert(3.2);
   list.insert(14);
   list.insert(43);
   list.insert(0);
   list.insert(9);
   list.insert(2);

   cout << "Contents of linked list before insert sort:\n";
   list.display();


   list.insertSort();

   cout << "Contents of linked list after insert sort:\n";
   list.display();

   return 0;

【问题讨论】:

考虑一下:current-&gt;prevcurrent == head 是什么? @1201ProgramAlarm 我考虑过,但current 永远不会等于head,因为current = markermarker = head-&gt;next。在 for 循环中,marker 递增,因此它永远不会等于 head @1201ProgramAlarm 我认为是正确的。在您的内部循环中,current 倒退。在某些时候它将是head,这意味着current-&gt;prev 是NULL。 @MFisherKDX 和@1201ProgramAlarm 你是对的,内部循环运行while (current != nullptr) 所以我只是将其更改为while (current-&gt;prev != nullptr),现在它可以工作了。感谢您的帮助。如此简单的疏忽一定意味着该睡觉了。 如果我没记错的话,它更有效,因为子列表总是有序的,所以如果被比较的元素大于排序子列表中的最后一个元素,它就不需要去通过头部的每个元素 - 它可以与最后一个元素进行比较并放置在最后。我仍在尝试了解如何使用 Big O 分析算法的效率,但代码似乎通过这种方式进行的比较较少。 【参考方案1】:

我想出了如何解决这个问题。内部循环运行while (current != nullptr),因此当电流位于头部并被分配current-&gt;prev 时,它指向nullptr。我将while循环条件更改为current-&gt;prev != nullptr,现在它运行正常,因为它从不指向nullptr。

【讨论】:

以上是关于如何在双向链表 C++ 上使用插入排序?的主要内容,如果未能解决你的问题,请参考以下文章

小白上手写的第一个双向链表(C++)

双向链表模板向量中的输入排序(C++)

双向链表(c++实现)

C++基于双向链表的List

双向链表中按字母顺序排序的链接

二叉搜索树与双向链表(Python and C++版本)