如何反向链表C++

How to reverse linked list C++

本文关键字:C++ 链表 何反      更新时间:2023-10-16

可能重复:
反转单链表
反转链接列表?

我一直在想如何以相反的顺序显示数字链接列表的内容。我试着改变周围的节点,但我想不通。它是一个单独链接的列表。我想过实现一个堆栈。有更简单的方法吗?这是我的密码。我需要这个函数在头文件中,它将在main.cpp中实现。我今天和昨天已经尝试了几个小时,这真的是最后的手段。我有几页关于失败算法的笔记。以及谷歌搜索页面,但似乎什么都不起作用。如果我使用Microsoft Visual Studio 2010(不是我的第一选择)有什么不同的话。我提供的代码与我尝试的不一样,因为它都失败了,而且通常会产生错误。

#ifndef _LINKEDLIST_H
#define _LINKEDLIST_H
#include <iostream>
#include <string>
#include <stack>
#include "Node.h"
using namespace std;
using namespace bruno;
namespace bruno
{
template< typename T>
class LinkedList
{
    private:        Node<T>  * head;
                    Node<T>  * tail;
                    int numberOfNodes;
    public:         LinkedList();
                    ~LinkedList();
                    int length(); 
                    Node<T>  * getHead() { return head; };
                    Node<T>  * getTail() { return tail; };
                    void insertInFront(T d);
                    void insertInBack(T d);
                    static void listContents( Node<T> * head);  
                    static T  sum( Node<T>  * head);    //     assume head is not NULL at call
                    static void  increment( Node<T>  * head, T val); 
                    static void reverseListContents( Node<T> * head, Node<T> * tail, int n );
};

   template< typename T >
   LinkedList<T>::LinkedList()
   {
       head = tail = NULL;
       numberOfNodes = 0;
   }

   template< typename T >
   LinkedList<T>::~LinkedList()
   {
   }

   template< typename T >
   int LinkedList<T>::length()
   { 
       return numberOfNodes; 
   }

   template< typename T >
   void LinkedList<T>::insertInFront(T d)
   {
        Node<T> * p =  new Node<T>;
        p->data  =  d;
        p->next  = head;
        head = p;
        if ( tail == NULL )
            tail = p;
        numberOfNodes++;
   }


   template< typename T >
   void LinkedList<T>::insertInBack(T d)
   {
        if ( tail == NULL )
            insertInFront(d);
        else {
                tail->next = new Node<T>;
                tail = tail->next;
                tail -> data = d;
                tail -> next = NULL;
        }
        numberOfNodes++;
   }

   template< typename T >                       
   void LinkedList<T>::listContents(Node<T> * head)
   {
        if (head == NULL)  return;
        else
        {      cout <<  head->data  << "  ->  ";
               listContents( head -> next );
        }
   }


   template< typename T >                       
   T LinkedList<T>::sum(Node<T> * head)
   {
        if ( (head->next) == NULL )  return  head->data;
        else
             return  ( head->data    +   sum( head->next ) );
   }


   template< typename T >                       
   void LinkedList<T>::increment(Node<T> * head, T  val)
   {
        if ( head == NULL )  return;
        else
        {
            head->data += val;                    // add val to current data value
            increment( head->next, val );
        }
   }
   template< typename T >
   void LinkedList<T>::reverseListContents (Node<T> * head, Node<T> * tail, int n)
   {
       //clueless!

   }

}
#endif 

您可以这样做:

1) 找到最后一个节点并打印。

2) 遍历链接列表,找到将上次打印的节点作为其下一个节点的节点,然后打印它。

3) 转到步骤2,直到没有更多节点可打印为止。

递归解决方案应该执行

Node * Reverse( Node * ptr , Node * previous)
{
    Node * temp;
    if(ptr->next == NULL) {
        ptr->next = previous;
        return ptr;
    } else {
        temp = Reverse(ptr->next, ptr);
        ptr->next = previous;
        return temp;
    }
}

用法:

ReversedList = Reverse(head, NULL);

通常,您可以将Node类视为链表,不需要单独的类。

有两种通用方法可以反转单链表。

一种是更改指针,使尾部节点变为头部节点,反之亦然,并且中间的所有指针都变为另一种方式。每个数据项都与以前保持在同一个节点中。

另一种方法是保持节点的结构不变,但移动数据。

因为您将函数命名为reverseListContents,所以我怀疑您正试图执行后者。这更难做到。

反转列表的结构(第一种方法)可以通过一个简单的循环来完成。

你见过有人翻最后一张牌,把放在桌子上的一连串重叠的扑克牌翻过来吗?这与指针改变方向的方式类似。

非常仔细地观看这个YouTube视频,并在C++中实现相同的东西:

http://www.youtube.com/watch?v=yW1Ch7eo4g4

不要忘记更新headtail指针,它们交换节点。

我不会为您编写详细代码,但会给出伪代码:

void printLinkedListReverseOrder(NodeType * ptr)
{
    // Be defensive, Don't assume proper input. Validate it first
    if(NULL == ptr) return;
    // If this node is not the last, print it's next node first
    if(NULL != ptr->next) printLinkedListReverseOrder(ptr->next);
    // When all nodes after it is printed, then print the node itself
    print(ptr);
}

请注意,这使用递归,这对于大的链表来说是不好的。如果你有一个大的链表,并且想要使用循环,那么你可以在打印节点之前使用堆栈来存储节点。