冒泡排序双向链表

Bubble sort a doubly linked list

我浏览了一堆线程,试图了解链表和冒泡排序到底发生了什么,我想我了解了其中的大部分内容。

现在,当我进入排序功能时,我的程序只是崩溃了,我不确定为什么。希望另一双眼睛能看到我看不到的东西。

非常感谢任何帮助。

DoublyList.h:

#include "listNode.h"

#ifndef DOUBLYLIST_H
#define DOUBLYLIST_H

template <typename T>
class DoublyList
{
    public:
        DoublyList();
        ~DoublyList();
        void addFront(T d);
        void addBack(T d);
        T removeFront();
        T removeBack();
        T peak();
        bool isEmpty();
        int getSize();
        void printList();
        void sortList();

    private:
        ListNode<T> *front;
        ListNode<T> *back;
        int numOfElements;
};

template <typename T>
DoublyList<T>::DoublyList(){
    front = NULL;
    back = NULL;
    numOfElements = 0;
}
template <typename T>
DoublyList<T>::~DoublyList(){
    if(numOfElements!=0){

        ListNode<T> *current;
        current = front;
        while (current != back)
        {
            ListNode<T> *temp = current;
            current = current->next;
            temp->next = NULL;
            temp->prev = NULL;
            delete temp;
            numOfElements--;
        }
        //at this point current = back, now delete it
        current->next = NULL;
        current->prev = NULL;
        delete current;
        numOfElements--;
    }
    //this is a safeguard if you create a LL and then delete it without doing anything to it
    else{
        cout<<"deleted empty LL"<<endl;
        delete front;
        delete back;
    }
}
template <typename T>
void DoublyList<T>::addFront(T d)
{
    ListNode<T> *node = new ListNode<T>();
    node->data = d;
    if (isEmpty()){
        back = node;
    }
    else{
        front->prev = node;
    }
    node->next = front;
    front = node;
    ++numOfElements;
}
template <typename T>
T DoublyList<T>::removeFront()
{
    if (isEmpty()){
        return T();
    }
    else
    {
        ListNode<T>* temp = front;
        if (front->next == 0){
            back = 0;
        }
        else
        {
            front->next->prev = 0;
        }
        front = front->next;
        temp->next = 0;
        T theData = temp->data;
        delete temp;
        --numOfElements;
        return theData;
    }
}
template <typename T>
void DoublyList<T>::addBack(T d)
{
    ListNode<T> *node = new ListNode<T>();
    node->data = d;
    if (isEmpty()){
        front = node;
    }
    else{
        back->next = node;
    }
    node->prev = back;
    back = node;
    ++numOfElements;
}
template <typename T>
T DoublyList<T>::removeBack()
{
    if (isEmpty()) {
        return T();
    }
    else
    {
        ListNode<T>* temp;
        temp = back;
        if (back->prev == 0){
            front = 0;
        }
        else{
            back->prev->next = 0;
        }
        back = back->prev;
        temp->prev = 0;    
        T theData = temp->data;
        delete temp;
        --numOfElements;
        return theData;
    }
}
template <typename T>
T DoublyList<T>::peak()
{
    if (isEmpty()) {
        return T();
    }
    return front->data;
}
template <typename T>
int DoublyList<T>::getSize(){
    return numOfElements;
}
template <typename T>
bool DoublyList<T>::isEmpty(){
    if(numOfElements == 0){
        return true;
    }
    else{
        return false;
    }
}
template <typename T>
void DoublyList<T>::printList(){
    if(numOfElements!=0){
        ListNode<T> *current = front;
        while(current!=back)
        {
            cout<<current->data<<endl;
            current = current->next;
        }
        cout<<back->data<<endl;
    }
    else{
        cout<<"list is empty"<<endl;
    }
}


template <typename T>
void DoublyList<T>::sortList(){
    int size = getSize();
    ListNode<T> *current;
    ListNode<T> *dummy;
    ListNode<T> *next;

    if(current == NULL) return;
    if(current -> next == NULL) return;

    int swapped = 1;
    while(swapped){
        swapped = 0; //last pass unless there is a swap
        while(current -> next != NULL){
            if(current-> data < current -> next -> data){
                swapped = 1; //swap, will need to re-enter while loop
                //actual number swap
                dummy -> data = current -> data;
                current -> data = current -> next -> data;
                current -> next -> data = dummy -> data;
            }
            current = current -> next;
        }
    }

}

#endif

listNode.h:

#include <iostream>
#ifndef LISTNODE_H
#define LISTNODE_H

using namespace std;
template <typename T>
class ListNode
{
    public:
        T data;//the data that we will store
        ListNode();
        ListNode(int d);
        ~ListNode();
        ListNode *next;//int and ptr and the member variables
        ListNode *prev;
};
template <typename T>
ListNode<T>::ListNode(int d){
    data = d;
    next = NULL;
    prev = NULL;
}
template <typename T>
ListNode<T>::ListNode(){}
template <typename T>
ListNode<T>::~ListNode(){
    delete next;
    delete prev;
    cout<<"deleted Node"<<endl;
}
#endif

testList.cpp

#include <iostream>
#include "doublyList.h"
#include "genericQueue.h"




int main(){
    DoublyList<int> testQueue;
    testQueue.addBack(3);
    testQueue.addBack(5);
    testQueue.addBack(2);
    testQueue.addBack(10);
    testQueue.addBack(1);

    cout << "Before Sort: " << endl;
    testQueue.printList();

    cout << "After Sort: " << endl;
    testQueue.sortList();
    testQueue.printList();

}

首先,您需要在排序函数中初始化 current,

current = first; 


template <typename T>
void DoublyList<T>::sortList(){

ListNode<T> *current;
ListNode<T> *next;

T tmp;
current = front;
if(current == NULL) return;
if(current -> next == NULL) return;

int swapped = 1;
while(swapped){
    swapped = 0; //last pass unless there is a swap
    while(current->next != nullptr){
        if(current->data < current->next->data){
            swapped = 1; //swap, will need to re-enter while loop
            //actual number swap
            tmp = current->data;
            current->data = current->next->data;
            current->next->data = tmp;
        }
        current = current -> next;  
    }
    if (swapped)          // go back to start of list for next pass
       current = front;
}

}

到目前为止我能找到的错误是:

  1. 您的默认 ListNode() 构造函数不会使 nextprev 指针为空。
  2. void DoublyList<T>::sortList() 中你没有初始化 dummy,所以它只是指向任何地方。其实根本没有必要使用节点列表,直接使用T.
  3. 类型的变量即可
  4. 您没有在同一个函数中初始化 current,您实际上应该将 current 重置为例如front 在每个外循环的开头。
  5. 您根本不使用 next(也不需要),所以只需将其删除。

总而言之,这就是 void DoublyList<T>::sortList() 的样子:

template <typename T>
void DoublyList<T>::sortList(){
    int size = getSize();
    ListNode<T> *current=front;
    T dummy;

    if (current == NULL) return;
    if (current->next == NULL) return;

    int swapped = 1;
    while (swapped){
        current = front;
        swapped = 0; //last pass unless there is a swap
        while (current->next != NULL){
            if (current->data < current->next->data){
                swapped = 1; //swap, will need to re-enter while loop
                //actual number swap
                dummy = current->data;
                current->data = current->next->data;
                current->next->data = dummy;
            }
            current = current->next;
        }
    }
}

这是我对 ListNode 构造函数的建议。

template <typename T>
ListNode<T>::ListNode() :
    next(nullptr), 
    prev(nullptr), 
    data{}
{}

除此之外,我也同意 DaveB 的观点,交换指针是您实际应该使用的方法。