c++ 如何实现双向链表的反向元素访问(当元素非常接近末尾时)[已关闭]

xlpyo6sf  于 2022-12-15  发布在  其他
关注(0)|答案(1)|浏览(114)

已关闭。此问题需要details or clarity。当前不接受答案。
**想要改进此问题?**添加详细信息并通过editing this post阐明问题。

4天前关闭。
Improve this question
我正在尝试用C++实现一个双向链表,我正在做的成员函数之一是access元素,它会返回一个Node指针,我最初的实现是完全功能性的,但是我意识到有些情况下效率非常低,比如说这个链表有一百万个节点,那么访问999、第999个节点比从“最后一个”指针节点反向访问要慢得多。不幸的是,我的反向访问实现不起作用。我检查了for循环的范围,它绝对是正确的。
下面是相关的代码部分:

Node * getNode(int element) {
        if (element + 1 > listsize / 2) {
            Node * node = last;
            for (int i = 0; i < listsize - element - 1; i++)
                node = node -> previousnode;
            return node;
        }
        Node * node = head;
        for (int i = 0; i < element; i++)
            node = node -> nextnode;
        return node;
    }

我的整个程序可以在这里找到,如果有人想澄清关于范围、声明等的问题:

#include <bits/stdc++.h>
using namespace std;

class Node {
public:
    int data;
    Node * nextnode;
    Node * previousnode;
};

class DoublyLinkedList {
public:
    Node * head = new Node;
    Node * last = head;
    int listsize = 0;
    DoublyLinkedList(int size) {
        Node * previous = nullptr;
        Node * current = nullptr;
        previous = head;
        for (int i = 1; i < size; i++) {
            current = new Node;
            previous -> nextnode = current;
            current -> previousnode = previous;
            previous = current;
            last = current;
        }
        listsize = size;
        head -> previousnode = nullptr;
        last -> nextnode = nullptr;
    }
    DoublyLinkedList(int size, int fill) {
        Node * previous = nullptr;
        Node * current = nullptr;
        previous = head;
        head -> data = fill;
        for (int i = 1; i < size; i++) {
            current = new Node;
            previous -> nextnode = current;
            current -> previousnode = previous;
            current -> data = fill;
            previous = current;
            last = current;
        }
        listsize = size;
        head -> previousnode = nullptr;
        last -> nextnode = nullptr;
    }
    Node * getNode(int element) {
        if (element + 1 > listsize / 2) {
            Node * node = last;
            for (int i = 0; i < listsize - element - 1; i++)
                node = node -> previousnode;
            return node;
        }
        Node * node = head;
        for (int i = 0; i < element; i++)
            node = node -> nextnode;
        return node;
    }
    void editNode(int element, int value) {
        Node * node = getNode(element);
        node -> data = value;
        return;
    }
    void push_front(int value = 0) {
        Node * pushNode = new Node;
        pushNode -> nextnode = head;
        pushNode -> data = value;
        head -> previousnode = pushNode;
        head = pushNode;
        head -> previousnode = nullptr;
        listsize++;
    }
    void pop_front() {
        Node * newhead = head -> nextnode;
        delete head;
        head = newhead;
        head -> previousnode = nullptr;
        listsize--;
    }
    void push_back(int value = 0) {
        Node * pushNode = new Node;
        last -> nextnode = pushNode;
        last = pushNode;
        pushNode -> data = value;
        last -> nextnode = nullptr;
        listsize++;
    }
    void pop_back() {
        Node * newlast = last -> previousnode;
        delete last;
        last = newlast;
        last -> nextnode = nullptr;
        listsize--;
    }
    int size() {
        return listsize;
    }
    void displayList() {
        displayList(0, listsize);
    }
    void displayList(int start, int finish) {
        cout << "List: ";
        Node * a = getNode(start);
        cout << a -> data << " <=> ";
        for (int i = start + 1; i < finish - 1; i++) {
            a = a -> nextnode;
            cout << a -> data << " <=> ";
        }
        a = a -> nextnode;
        cout << a -> data;
        cout << "\n\n";
    }
};

int main(int argc, const char * argv[]) {
    DoublyLinkedList testlist(5, 3);
    

    testlist.push_front(8);
    testlist.push_back(10);
    testlist.displayList();
    cout << testlist.last -> data << "a\n";
    Node * testnode = testlist.last;
    cout << testnode -> data << "b\n";
    testnode = testnode -> previousnode;
    cout << testnode -> data << "c\n";

    
    /*testlist.editNode(1, 22);
    Node * testnode = testlist.getNode(2);
    testnode = testnode -> previousnode;
    cout << testnode -> data << endl;*/

    /*
    int inputc;
    string operation;
    int number;
    cin >> inputc;
    cout << "Initial ";
    testlist.displayList();
    while (inputc--) {
        cin >> operation;
        if (operation == "pushback") {
            cin >> number;
            testlist.push_back(number);
        } else if (operation == "popback")
            testlist.pop_back();
        else if (operation == "pushfront") {
            cin >> number;
            testlist.push_front(number);
        } else if (operation == "popfront")
            testlist.pop_front();
        else if (operation == "access") {
            cin >> number;
            Node * n = testlist.getNode(number);
            cout << "Node stores value: " << n -> data << "\n";
        } else if (operation == "size") {
            int a = testlist.size();
            cout << "Size: " << a << "\n";
        } else if (operation == "edit") {
            cin >> number;
            int edit;
            cin >> edit;
            testlist.editNode(number, edit);
        } else if (operation == "partialdisplay") {
            int start, end;
            cin >> start >> end;
            testlist.displayList(start, end);
        }
        testlist.displayList();
    }
    */
}

我已经测试了“previousnode”指针,以及所有的push和pop函数,你可以看到我所做的一些测试,在main()函数中被注解为多行注解。

mnemlml8

mnemlml81#

您的push_front有7行代码,但push_back只有6行。
PS:按索引/位置访问元素在某种程度上挫败了使用双链表的目的(一般来说)。

相关问题