在双链表中的某个位置删除

时间:2018-06-23 21:14:27

标签: c++ linked-list

我在编写此函数时遇到了麻烦,该函数是在双链表中的某个位置删除的。我觉得我正在泄漏内存,并且我没有为双重链接列表使用此属性。

代码如下:

template <class T>
void DoubleLinkedLists<T>::deletePosition(int pos) {
    Node* prev = new Node;
    Node* current = head;

    for(int i = 1; i < pos; i++) {
        prev = current;
        current = current->next;
    }
    prev->next = current->next;
}

这几乎是我对单个链表所做的,所以我知道这是不对的。如果有人对双重链接列表有任何建议,我将不胜感激。

编辑:

我认为这现在可以正常工作:

    template <class T>
    void DoubleLinkedLists<T>::deletePosition(int pos) {
        Node* temp = nullptr;
        Node* current = head;

        for(int i = 1; i < pos; i++) {
            temp = current;
            current = current->next;
        }
        temp->previous = current->previous;
        temp->next = current->next;
    }

这是完整的代码:

#ifndef DoubleLinkedLists_h
#define DoubleLinkedLists_h

template <class T>
class DoubleLinkedLists {
private:

    struct Node {
        T data;
        Node* next;
        Node* previous;
    };

    Node* head;
    Node* tail;

public:
    // Constructors
    DoubleLinkedLists() : head(nullptr), tail(nullptr) {}                  // empty constructor
    DoubleLinkedLists(DoubleLinkedLists const& value);                     // copy constructor
    DoubleLinkedLists<T>(DoubleLinkedLists<T>&& move) noexcept;            // move constuctor
    DoubleLinkedLists<T>& operator=(DoubleLinkedLists&& move) noexcept;    // move assignment operator
    ~DoubleLinkedLists();                                                  // destructor

    // Overload operators
    DoubleLinkedLists& operator=(DoubleLinkedLists const& rhs);
    friend std::ostream& operator<<(std::ostream& str, DoubleLinkedLists<T> const& data) {
        data.display(str);
        return str;
    }

    // Member functions
    void swap(DoubleLinkedLists& other) noexcept;
    void push(const T& theData);
    void push(T&& theData);
    void display(std::ostream& str) const;
    void insertHead(const T& theData);
    void insertTail(const T& theData);
    void insertPosition(int pos, const T& theData);
    void deleteHead();
    void deleteTail();
    void deletePosition(int pos);
    bool search(const T& x);
};

template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists const& value) : head(nullptr), tail(nullptr) {
    for(Node* loop = value->head; loop != nullptr; loop = loop->next) {
        push(loop->data);
    }
}

template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists<T>&& move) noexcept : head(nullptr), tail(nullptr) {
    move.swap(*this);
}

template <class T>
DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists<T> &&move) noexcept {
    move.swap(*this);
    return *this;
}

template <class T>
DoubleLinkedLists<T>::~DoubleLinkedLists() {
    while(head != nullptr) {
        deleteHead();
    }
}

template <class T>
void DoubleLinkedLists<T>::swap(DoubleLinkedLists<T> &other) noexcept {
    using std::swap;
    swap(head,other.head);
    swap(tail,other.tail);
}

template <class T>
void DoubleLinkedLists<T>::push(const T& theData) {
    Node* newNode = new Node;
    newNode->data = theData;
    newNode->previous = tail;

    if(head == nullptr) {
        head = newNode;
    }
    else {
        tail->next = newNode;
    }
    tail = newNode;
}

template <class T>
void DoubleLinkedLists<T>::push(T&& theData) {
    Node* newNode = new Node;
    newNode->data = theData;
    newNode->previous = tail;

    if(head == nullptr) {
        head = newNode;
    }
    else {
        tail->next = newNode;
    }
    tail = newNode;
}

template <class T>
void DoubleLinkedLists<T>::display(std::ostream &str) const {
    for(Node* loop = head; loop != nullptr; loop = loop->next) {
        str << loop->data << "\t";
    }
    str << "\n";
}

template <class T>
void DoubleLinkedLists<T>::insertHead(const T &theData) {
    Node* newNode = new Node;
    newNode->data = theData;
    newNode->next = head;
    head->previous = newNode;
    head = newNode;
}

template <class T>
void DoubleLinkedLists<T>::insertTail(const T &theData) {
    Node* newNode = new Node;
    newNode->data = theData;
    newNode->previous = tail;
    tail->next = newNode;
    tail = newNode;
}

template <class T>
void DoubleLinkedLists<T>::insertPosition(int pos, const T &theData) {
    if (pos < 0) {
        throw std::invalid_argument("pos is not a valid index");
    }

    Node* current = head;
    Node* previous = nullptr;

    while(pos-- > 0) {
        if(!current) {
            throw std::invalid_argument("pos is not a valid index");
        }
        previous = current;
        current = current->next;
    }

    Node* newNode = new Node;
    newNode->data = theData;

    newNode->previous = previous;
    newNode->next = current;

    if(newNode->previous) {
        newNode->previous->next = newNode;
    }
    else {
        head = newNode;
    }

    if(newNode->next) {
        newNode->next->previous = newNode;
    }
    else {
        tail = newNode;
    }
}

template <class T>
void DoubleLinkedLists<T>::deleteHead() {
    if (head != nullptr) {
        Node* old = head;
        head = head->next;
        delete old;
    }
    else {
        throw std::invalid_argument("the list is empty!");
    }
}

template <class T>
void DoubleLinkedLists<T>::deleteTail() {
    if(head != nullptr) {
        Node* prev = nullptr;
        Node* current =  head;
        while(current->next != nullptr) {
            prev = current;
            current = current->next;
        }
        tail = prev;
        prev->next = nullptr;
        delete current;
    }
    else {
        throw std::invalid_argument("The list is already empty, nothing to delete.");
    }
}

template <class T>
void DoubleLinkedLists<T>::deletePosition(int pos) {
    Node* temp = nullptr;
    Node* current = head;

    for(int i = 1; i < pos; i++) {
        temp = current;
        current = current->next;
    }
    temp->previous = current->previous;
    temp->next = current->next;
}

template <class T>
bool DoubleLinkedLists<T>::search(const T &x) {
    Node* current = head;
    while(current != nullptr) {
        if(current->data == x) {
            return true;
        }
        current = current->next;
    }
    return false;
}
#endif /* DoubleLinkedLists_h */

这是对其进行测试的main.cpp文件:

#include <iostream>
#include "DoubleLinkedLists.h"



int main(int argc, const char * argv[]) {



    ///////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////// Double Linked List //////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////
    DoubleLinkedLists<int> obj;
    obj.push(2);
    obj.push(4);
    obj.push(6);
    obj.push(8);
    obj.push(10);
    std::cout<<"\n--------------------------------------------------\n";
    std::cout<<"---------------Displaying All nodes---------------";
    std::cout<<"\n--------------------------------------------------\n";
    std::cout << obj << std::endl;

    std::cout<<"\n--------------------------------------------------\n";
    std::cout<<"----------------Inserting At Start----------------";
    std::cout<<"\n--------------------------------------------------\n";
    obj.insertHead(50);
    std::cout << obj << std::endl;

    std::cout<<"\n--------------------------------------------------\n";
    std::cout<<"-----------------Inserting At End-----------------";
    std::cout<<"\n--------------------------------------------------\n";
    obj.insertTail(20);
    std::cout << obj << std::endl;

    std::cout<<"\n--------------------------------------------------\n";
    std::cout<<"-------------Inserting At Particular--------------";
    std::cout<<"\n--------------------------------------------------\n";
    obj.insertPosition(5,60);
    std::cout << obj << std::endl;

    std::cout<<"\n--------------------------------------------------\n";
    std::cout<<"----------------Deleting At Start-----------------";
    std::cout<<"\n--------------------------------------------------\n";
    obj.deleteHead();
    std::cout << obj << std::endl;

    std::cout<<"\n--------------------------------------------------\n";
    std::cout<<"----------------Deleting At End-----------------";
    std::cout<<"\n--------------------------------------------------\n";
    obj.deleteTail();
    std::cout << obj << std::endl;

    std::cout<<"\n--------------------------------------------------\n";
    std::cout<<"--------------Deleting At Particular--------------";
    std::cout<<"\n--------------------------------------------------\n";
    obj.deletePosition(5);
    std::cout << obj << std::endl;
    std::cout << std::endl;

    obj.search(8) ? printf("Yes"):printf("No");

    return 0;
}    

1 个答案:

答案 0 :(得分:2)

因此,您需要执行以下操作。请注意,您的代码不会处理索引超出范围的情况(即,指定的位置为负数或更长的列表)。看起来您不需要维护列表长度(在链接的代码中),因此我在for循环以及for循环之后添加了current != nullptr的检查以处理{{ 1}}比列表长。在那种情况下,现在代码将什么都不做,但是您可能会抛出超出范围的异常或类似的东西来指示无效条件。在卸下头部的情况下,您还需要注意固定头部指针。我假设您也可能有尾巴指针,因此您需要添加检查以查看是否要除去尾巴并进行修复。

注意
我没有对此进行编译,因此可能会有一两个错字,但这至少应该为您指明正确的方向。

pos