反向链接 反向代理
Reversing a Linked List is an interesting problem in data structure and algorithms. In this tutorial, we’ll be discussing the various algorithms to reverse a Linked List and then implement them using Java.
反向链接列表是数据结构和算法中一个有趣的问题。 在本教程中,我们将讨论各种算法来反向链接列表 ,然后使用Java实现它们。
反向链接列表 (Reverse a Linked List)
LinkedList is a data structure which stores the data in a linear way. Though not in a contiguous way.
LinkedList是一种数据结构,它以线性方式存储数据。 虽然不是连续的。
Every element of a LinkedList contains a data part and an address to the next element of the LinkedList.
LinkedList的每个元素都包含一个数据部分和LinkedList的下一个元素的地址。
LinkedList elements are popularly known as nodes.
LinkedList元素通常称为节点。
In order to reverse a LinkedList in place, we need to reverse the pointers such that the next element now points to the previous element.
为了使LinkedList反向,我们需要反向指针,以便下一个元素现在指向上一个元素。
Following is the input and output.
以下是输入和输出。
![linkedlist reverse input](https://cdn.journaldev.com/wp-content/uploads/2018/08/linkedlist-reverse-input.png)
Input
输入项
![linkedlist reverse output](https://i-blog.csdnimg.cn/blog_migrate/fdfa6142a9229b1b63634eb5bded7fe2.png)
Output
输出量
The head of the LinkedList is the first node. No other element has the address stored for this.
LinkedList的头是第一个节点。 没有其他元素为此存储地址。
The tail of the LinkedList is the last node. The next address stored in this node is null
.
LinkedList的尾部是最后一个节点。 存储在此节点中的下一个地址为null
。
We can reverse a LinkedList such that the head and tail also get changed using:
我们可以反转LinkedList,使头部和尾部也可以使用以下方式更改:
- Iterative Approach 迭代法
- Recursive Approach 递归方法
反向链接列表的迭代方法 (Iterative Approach to Reverse a Linked List)
To reverse a LinkedList iteratively, we need to store the references of the next and previous elements, so that they don’t get lost when we swap the memory address pointers to the next element in the LinkedList.
要迭代地反转LinkedList,我们需要存储下一个和上一个元素的引用,以便在将内存地址指针交换到LinkedList中的下一个元素时,它们不会丢失。
Following illustration demonstrates how we will reverse our LinkedList by changing the references.
下图说明了如何通过更改引用来反转LinkedList。
Create 3 instances: current, next, previous.
创建3个实例:当前,下一个,上一个。
Loop the following till current is NOT null:
循环以下,直到current不为空:
- Save the next Node of the current element in the next pointer. 将当前元素的下一个节点保存在下一个指针中。
- Set the next of the
current
Node to theprevious
. This is the MVP line. 将current
节点的下一个设置为上previous
。 这是MVP行。 - Shift previous to current. 从上一个移到当前。
- Shift the current element to next. 将当前元素移到下一个。
In the end, since the current has gone one place ahead of the last element, we need to set the head to the last element we reached. This is available in previous.
Set head to previous. Thus we have our new head of the LinkedList which is the last element of the older LinkedList.
最后,由于电流已经比最后一个元素领先一个位置,因此我们需要将head设置为到达的最后一个元素。 这是以前可用的。
前往上一个。 因此,我们有了LinkedList的新头,它是旧LinkedList的最后一个元素。
Here is a very simple implementation of LinkedList. Note that this is not a production-ready implementation and we have kept it simple so that our focus remains on the algorithm to reverse the Linked List.
这是LinkedList的非常简单的实现。 请注意,这不是可用于生产的实现,因此我们将其保持简单,因此我们将重点放在反转链表的算法上。
package com.journaldev.linkedlist.reverse;
public class MyLinkedList {
public Node head;
public static class Node {
Node next;
Object data;
Node(Object data) {
this.data = data;
next = null;
}
}
}
The Java Program to reverse a Linked List iteratively and printing its elements is given below:
下面给出了Java程序以迭代方式反向链接列表并打印其元素的情况:
package com.journaldev.linkedlist.reverse;
import com.journaldev.linkedlist.reverse.MyLinkedList.Node;
public class ReverseLinkedList {
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.head = new Node(1);
myLinkedList.head.next = new Node(2);
myLinkedList.head.next.next = new Node(3);
printLinkedList(myLinkedList);
reverseLinkedList(myLinkedList);
printLinkedList(myLinkedList);
}
public static void printLinkedList(MyLinkedList linkedList) {
Node h = linkedList.head;
while (linkedList.head != null) {
System.out.print(linkedList.head.data + " ");
linkedList.head = linkedList.head.next;
}
System.out.println();
linkedList.head = h;
}
public static void reverseLinkedList(MyLinkedList linkedList) {
Node previous = null;
Node current = linkedList.head;
Node next;
while (current != null) {
next = current.next;
current.next = previous;
previous = current;
current = next;
}
linkedList.head = previous;
}
}
Output:
输出:
1 2 3
3 2 1
递归反向链接列表 (Reverse a Linked List Recursively)
To reverse a LinkedList recursively we need to divide the LinkedList into two parts: head and remaining.
Head points to the first element initially. Remaining points to the next element from the head.
要递归地反转LinkedList,我们需要将LinkedList分为两部分:头部分和剩余部分。
Head最初指向第一个元素。 其余部分指向头部的下一个元素。
We traverse the LinkedList recursively until the second last element.
Once we’ve reached the last element set that as the head.
From there we do the following until we reach the start of the LinkedList.
我们以递归方式遍历LinkedList,直到倒数第二个元素为止。
一旦到达最后一个元素,就将其设置为头部。
从那里开始执行以下操作,直到到达LinkedList的开始。
node.next.next = node;
node.next = null;
node.next.next = node;
node.next = null;
To not lose a track of the original head, we’ll save a copy of the head instance.
为了不丢失原始磁头,我们将保存磁头实例的副本。
Following is the illustration of the above procedure.
以下是上述过程的说明。
The Java program to reverse a LinkedList recursively is:
递归地反转LinkedList的Java程序是:
public static Node recursiveReverse(Node head) {
Node first;
if (head==null || head.next == null)
return head;
first = recursiveReverse(head.next);
head.next.next = head;
head.next = null;
return first;
}
We just pass the head.next in the recursive call in order to go to the end of the LinkedList.
我们只需在递归调用中传递head.next即可到达LinkedList的末尾。
Once we reach the end, we set the second last element as the next of the last element and set the next pointer of second last element to NULL. The last element will be marked as the new head.
一旦到达末尾,就将倒数第二个元素设置为倒数第二个元素,并将倒数第二个元素的下一个指针设置为NULL。 最后一个元素将被标记为新头。
Use the following code to reverse the linked list using the recursive approach.
使用以下代码通过递归方法来反向链接列表。
myLinkedList.head = recursiveReverse(myLinkedList.head);
The output will remain as the previous iterative approach.
输出将保留为以前的迭代方法。
反向链接列表的时空复杂性 (Space Time Complexity of Reversing a Linked List)
Space Complexity – O(1)
空间复杂度– O(1)
反向链接 反向代理