如何仅使用两个指针来反转单链表? [英] How to reverse a singly linked list using only two pointers?

查看:137
本文介绍了如何仅使用两个指针来反转单链表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我会想知道是否存在一些逻辑来使用两个指针来反转链表。

I would be wondered if there exists some logic to reverse the linked list using only two pointers.

以下内容用于使用三个指针来反转单个链表即p,q,r:

The following is used to reverse the single linked list using three pointers namely p, q, r:

struct node
{
    int data;
    struct node *link;
};

void reverse()
{
    struct node *p = first,
                *q = NULL,
                *r;
    while (p != NULL)
    {
        r = q;
        q = p;
        p = p->link;
        q->link = r;
    }
    q = first;
}

是否有其他替代方法可以反转链表?在时间复杂度方面,反转单链表的最佳逻辑是什么?

Is there any other alternate to reverse the linked list? what would be the best logic to reverse a singly linked list, in terms of time complexity?

推荐答案

我讨厌成为承载者的坏消息,但我不认为你的三指针解决方案实际上是有效的。当我在以下测试工具中使用它时,根据以下输出将列表减少到一个节点:

I hate to be the bearer of bad news but I don't think your three-pointer solution actually works. When I used it in the following test harness, the list was reduced to one node, as per the following output:

==========
4
3
2
1
0
==========
4
==========

你不会得到比你的解决方案更好的时间复杂度,因为它是O(n),你必须访问每个节点来改变指针,但是你可以很容易地做一个只有两个额外的指针的解决方案,如下所示代码:

You won't get better time complexity than your solution since it's O(n) and you have to visit every node to change the pointers, but you can do a solution with only two extra pointers quite easily, as shown in the following code:

#include <stdio.h>

// The list element type and head.

struct node { 
    int data;
    struct node *link;
};
static struct node *first = NULL;

// A reverse function which uses only two extra pointers.

void reverse() {
    // curNode traverses the list, first is reset to empty list.
    struct node *curNode = first, *nxtNode;
    first = NULL;

    // Until no more in list, insert current before first and advance.
    while (curNode != NULL) {
        // Need to save next node since we're changing the current.
        nxtNode = curNode->link;

        // Insert at start of new list.
        curNode->link = first;
        first = curNode;

        // Advance to next.
        curNode = nxtNode;
    }
}

// Code to dump the current list.

static void dumpNodes() {
    struct node *curNode = first;
    printf ("==========\n");
    while (curNode != NULL) {
        printf ("%d\n", curNode->data);
        curNode = curNode->link;
    }
}

// Test harness main program.

int main (void) {
    int i;
    struct node *newnode;

    // Create list (using actually the same insert-before-first
    // that is used in reverse function.

    for (i = 0; i < 5; i++) {
        newnode = malloc (sizeof (struct node));
        newnode->data = i;
        newnode->link = first;
        first = newnode;
    }

    // Dump list, reverse it, then dump again.

    dumpNodes();
    reverse();
    dumpNodes();
    printf ("==========\n");

    return 0;
}

此代码输出:

==========
4
3
2
1
0
==========
0
1
2
3
4
==========

我认为是你以后,实际上可以这样做,因为一旦你加载了 / code>到遍历列表的指针中,您可以随意重新使用第一个

which I think is what you were after. It can actually do this since, once you've loaded up first into the pointer traversing the list, you can re-use first at will.

这篇关于如何仅使用两个指针来反转单链表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆