通过推送反向链接列表的顺序

时间:2015-02-19 15:25:00

标签: c++ c list

我正在尝试创建一个更改节点指针顺序的函数,以便反转原始列表。

我的解决方案基于迭代主列表,然后颠倒每个相邻节点的顺序:(n1)->(n2)在第一次迭代后将为(n1)<-(n2)

我的尝试:

Node push1(Node* curr) {
    if(curr == NULL || *curr == NULL) {
        return NULL;
    }
    Node temp = (*curr)->next;
    if(temp == NULL) {
        return NULL;
    }
    (*curr)->next = *curr;
    return temp;
}
/*******************************/
void reverse2(Node* head) {
    Node curr = *head;
    while(curr != NULL) {
        curr = push1(&curr);
    }
}

问题:我遇到了一个无限循环。我试图修复它,但然后列表没有逆序。有没有办法使用push1()的这种方法可行?

注意:我不是在寻找带有3个指针或递归的解决方案。

3 个答案:

答案 0 :(得分:1)

这有效,但有点傻了

Node* push1(Node** prev, Node* curr)
{
    Node* ret = curr->next;
    curr->next = *prev;
    (*prev)=curr;
    return ret;
}

void reverse2(Node** head)
{
    Node* prev = *head;
    if(!prev) return;
    Node* curr = prev->next;
    if(!curr) return;
    prev->next = 0;
    while(curr)
    {
        curr = push1(&prev,curr);
    }
    *head = prev;
}

答案 1 :(得分:1)

使用std :: stack&lt;&gt;这是相当容易的数据结构与std :: vector&lt;&gt;结合使用。回想一下,Stacks是一种容器,设计用于在LIFO上下文中操作(后进先出),其中元素仅从容器的一端插入和提取。

因此,在您的情况下,您将创建一个堆栈,按照您已有的顺序将您的节点添加到堆栈中,然后将它们从堆栈中弹回以反转节点的顺序。

我已经草拟了代码来执行此操作,但请注意,它未经过测试,您应该能够根据您的情况调整此想法:

#include <stack>
#include <vector>

std::vector<Node> reverseNodes(Node* currNode, Node* startNode) {
    std::vector<Node> reversed;
    std::stack<Node> nodeStack;

    // First add nodes to the stack:
    for (Node* aNode = currNode; aNode != startNode; aNode = aNode->next) {
        nodeStack.push(aNode);
    }

    // Next add your starting node to the stack (last-in):
    nodeStack.push(startNode);

    // Popping off of the stack reverses the order:
    while (!nodeStack.empty()) {
        reversed.push_back(nodeStack.pop());
    }

    // Return the nodes ordered from last->first:
    return reversed;
}

答案 2 :(得分:1)

这不可读或不可移植,但它不使用递归或其他变量:

struct list {
    list *next;
    /* ... */
};


list *
reverse(list *l)
{
    list *head = nullptr;

    while (l) {
         head    = (list *) ((uint64_t) head    ^ (uint64_t) l->next);
         l->next = (list *) ((uint64_t) l->next ^ (uint64_t) head);
         head    = (list *) ((uint64_t) head    ^ (uint64_t) l->next);

         l    = (list *) ((uint64_t) l    ^ (uint64_t) head);
         head = (list *) ((uint64_t) head ^ (uint64_t) l);
         l    = (list *) ((uint64_t) l    ^ (uint64_t) head);
    }

    return head;
}

诀窍是使用xor swaps