简体   繁体   English

推链表的相反顺序

[英]reverse order of linked list by push

i am trying to make a function that changes the order of the pointers of the nodes so that the original list is reversed. 我试图做一个函数,以更改节点的指针的顺序,以便原始列表是相反的。

my solution is based on iterating over the main list, then reversing the order of each 2 adjacent nodes: (n1)->(n2) would be (n1)<-(n2) after the first iteration. 我的解决方案基于迭代主列表,然后反转每个2个相邻节点的顺序: (n1)->(n2) (n1)<-(n2)在第一次迭代后将是(n1)<-(n2)

my try: 我的尝试:

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);
    }
}

PROBLEM: i ran through an infinity loop. 问题:我遇到了无限循环。 i tried to fix that but then the list didn't reverse order. 我试图解决此问题,但是列表没有颠倒顺序。 is there a way using this approach of push1() that could work? 有没有办法使用这种方法push1()可行?

NOTE: i am not seeking the solution with 3 pointers or recursion. 注意:我不寻求与3指针或递归的解决方案。

This works, but is a bit silly 这有效,但有点傻

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;
}

This is fairly easy using a std::stack<> data structure in combination with a std::vector<>. 结合使用std :: stack <>数据结构和std :: vector <>,这相当容易。 Recall that Stacks are a type of container, designed to operate in a LIFO context (last-in first-out), where the elements are inserted and extracted only from one end of the container. 回想一下,堆栈是一种容器,旨在在LIFO上下文(后进先出)中操作,在该上下文中,仅从容器的一端插入和提取元素。

So in your situation you will create a stack, add your nodes to the stack in the order you already have, then popping them back off the stack reverses the order of the nodes. 因此,在您所处的情况下,您将创建一个堆栈,按照已拥有的顺序将节点添加到堆栈中,然后将其从堆栈中弹出,以颠倒节点的顺序。

I have sketched the code to do this but note that it is not tested, you should be able to adapt this idea to you situation: 我已经草绘了执行此操作的代码,但是请注意,该代码未经测试,因此您应该能够将此想法适应您的情况:

#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;
}

This is not readable or portable but it does not use recursion or additional variables: 这是不可读或可移植的,但不使用递归或其他变量:

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;
}

The trick is to use xor swaps . 诀窍是使用xor交换

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM