コードが機能しない理由を誰かに教えてもらえますか? Javaで1つのリンクリストを逆にしたい:これはメソッド(正しく動作しません)
public void reverseList(){
Node before = null;
Node tmp = head;
Node next = tmp.next;
while(tmp != null){
if(next == null)
return;
tmp.next = before;
before = tmp;
tmp = next;
next = next.next;
}
}
そして、これはNodeクラスです:
public class Node{
public int data;
public Node next;
public Node(int data, Node next){
this.data = data;
this.next = next;
}
}
入力4-> 3-> 2-> 1で出力4を取得しました。デバッグして、ポインターを正しく設定しましたが、なぜ4だけを出力するのかわかりません。
Node next = tmp.next;
while(tmp != null){
では、tmp == nullの場合はどうなりますか?
しかし、ほとんどそれを手に入れました。
Node before = null;
Node tmp = head;
while (tmp != null) {
Node next = tmp.next;
tmp.next = before;
before = tmp;
tmp = next;
}
head = before;
または、より良い(?)命名で:
Node reversedPart = null;
Node current = head;
while (current != null) {
Node next = current.next;
current.next = reversedPart;
reversedPart = current;
current = next;
}
head = reversedPart;
アスキーアート:
<__<__<__ __ : reversedPart : head
(__)__ __ __
head : current: > > >
public Node<E> reverseList(Node<E> node) {
if (node == null || node.next == null) {
return node;
}
Node<E> currentNode = node;
Node<E> previousNode = null;
Node<E> nextNode = null;
while (currentNode != null) {
nextNode = currentNode.next;
currentNode.next = previousNode;
previousNode = currentNode;
currentNode = nextNode;
}
return previousNode;
}
リンクリストを逆にする方法は次のとおりです。
public void reverseList() {
Node<E> curr = head;
Node<E> pre = null;
Node<E> incoming = null;
while(curr != null) {
incoming = curr.next; // store incoming item
curr.next = pre; // swap nodes
pre = curr; // increment also pre
curr = incoming; // increment current
}
head = pre; // pre is the latest item where
// curr is null
}
リストを逆にするには、3つの参照が必要です:pre、curr、incoming
... pre curr incoming
... --> (n-1) --> (n) --> (n+1) --> ...
ノードを反転するには、単純なステーメントを使用できるように、pre vious要素を保存する必要があります。
curr.next = pre;
現在の要素の方向を逆にします。ただし、リストを反復処理するには、上記のステートメントを実行する前に着信要素を保存する必要があります。現在の要素の次の参照を反転させると、着信要素がわからなくなるためです。
デモコードは次のとおりです。
public class LinkedList<E> {
protected Node<E> head;
public LinkedList() {
head = null;
}
public LinkedList(E[] list) {
this();
addAll(list);
}
public void addAll(E[] list) {
for(int i = 0; i < list.length; i++)
add(list[i]);
}
public void add(E e) {
if(head == null)
head = new Node<E>(e);
else {
Node<E> temp = head;
while(temp.next != null)
temp = temp.next;
temp.next = new Node<E>(e);
}
}
public void reverseList() {
Node<E> curr = head;
Node<E> pre = null;
Node<E> incoming = null;
while(curr != null) {
incoming = curr.next; // store incoming item
curr.next = pre; // swap nodes
pre = curr; // increment also pre
curr = incoming; // increment current
}
head = pre; // pre is the latest item where
// curr is null
}
public void printList() {
Node<E> temp = head;
System.out.print("List: ");
while(temp != null) {
System.out.print(temp + " ");
temp = temp.next;
}
System.out.println();
}
public static class Node<E> {
protected E e;
protected Node<E> next;
public Node(E e) {
this.e = e;
this.next = null;
}
@Override
public String toString() {
return e.toString();
}
}
}
public class ReverseLinkedList {
public static void main(String[] args) {
Integer[] list = { 4, 3, 2, 1 };
LinkedList<Integer> linkedList = new LinkedList<Integer>(list);
linkedList.printList();
linkedList.reverseList();
linkedList.printList();
}
}
List: 4 3 2 1
List: 1 2 3 4
これが宿題ではなく、意図的にこれを「手動」で実行している場合は、使用することをお勧めします
Collections.reverse(list);
Collections.reverse()はvoidを返し、呼び出し後にリストが逆になります。
前、現在、次の3つのノードを持つことができます。
public void reverseLinkedlist()
{
/*
* Have three nodes i.e previousNode,currentNode and nextNode
When currentNode is starting node, then previousNode will be null
Assign currentNode.next to previousNode to reverse the link.
In each iteration move currentNode and previousNode by 1 node.
*/
Node previousNode = null;
Node currentNode = head;
while (currentNode != null)
{
Node nextNode = currentNode.next;
currentNode.next = previousNode;
previousNode = currentNode;
currentNode = nextNode;
}
head = previousNode;
}
public void reverse() {
Node prev = null; Node current = head; Node next = current.next;
while(current.next != null) {
current.next = prev;
prev = current;
current = next;
next = current.next;
}
current.next = prev;
head = current;
}
// Java program for reversing the linked list
class LinkedList {
static Node head;
static class Node {
int data;
Node next;
Node(int d) {
data = d;
next = null;
}
}
// Function to reverse the linked list
Node reverse(Node node) {
Node prev = null;
Node current = node;
Node next = null;
while (current != null) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
node = prev;
return node;
}
// prints content of double linked list
void printList(Node node) {
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.head = new Node(85);
list.head.next = new Node(15);
list.head.next.next = new Node(4);
list.head.next.next.next = new Node(20);
System.out.println("Given Linked list");
list.printList(head);
head = list.reverse(head);
System.out.println("");
System.out.println("Reversed linked list ");
list.printList(head);
}
}
OUTPUT: -
Given Linked list
85 15 4 20
Reversed linked list
20 4 15 85
よりエレガントな解決策は、再帰を使用することです
void ReverseList(ListNode current, ListNode previous) {
if(current.Next != null)
{
ReverseList(current.Next, current);
ListNode temp = current.Next;
temp.Next = current;
current.Next = previous;
}
}
私は再帰的な解決策が最適なものではないことを知っていますが、ここに追加したかっただけです:
public class LinkedListDemo {
static class Node {
int val;
Node next;
public Node(int val, Node next) {
this.val = val;
this.next = next;
}
@Override
public String toString() {
return "" + val;
}
}
public static void main(String[] args) {
Node n = new Node(1, new Node(2, new Node(3, new Node(20, null))));
display(n);
n = reverse(n);
display(n);
}
static Node reverse(Node n) {
Node tail = n;
while (tail.next != null) {
tail = tail.next;
}
reverseHelper(n);
return (tail);
}
static Node reverseHelper(Node n) {
if (n.next != null) {
Node reverse = reverseHelper(n.next);
reverse.next = n;
n.next = null;
return (n);
}
return (n);
}
static void display(Node n) {
for (; n != null; n = n.next) {
System.out.println(n);
}
}
}
わかりません...なぜこれをしないのですか:
private LinkedList reverseLinkedList(LinkedList originalList){
LinkedList reversedList = new LinkedList<>();
for(int i=0 ; i<originalList.size() ; i++){
reversedList.add(0, originalList.get(i));
}
return reversedList;
}
これは簡単だと思います。
私は以下のコードを試してみましたが、うまくいきます:
Node head = firstNode;
Node current = head;
while(current != null && current.next != null){
Node temp = current.next;
current.next = temp.next;
temp.next = head;
head = temp;
}
基本的に、1つのノードの次のポインターを次のノードに設定します。そのため、次からはすべてのノードがリストの最後に追加されます。
Node reverse_rec(Node start) {
if (start == null || start -> next == null) {
return start;
}
Node new_start = reverse(start->next);
start->next->next = start;
start->next = null;
return new_start;
}
Node reverse(Node start) {
Node cur = start;
Node bef = null;
while (cur != null) {
Node nex = cur.next;
cur.next = bef;
bef = cur;
cur = nex;
}
return bef;
}
public class SinglyLinkedListImpl<T> {
private Node<T> head;
public void add(T element) {
Node<T> item = new Node<T>(element);
if (head == null) {
head = item;
} else {
Node<T> temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = item;
}
}
private void reverse() {
Node<T> temp = null;
Node<T> next = null;
while (head != null) {
next = head.next;
head.next = temp;
temp = head;
head = next;
}
head = temp;
}
void printList(Node<T> node) {
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
System.out.println();
}
public static void main(String a[]) {
SinglyLinkedListImpl<Integer> sl = new SinglyLinkedListImpl<Integer>();
sl.add(1);
sl.add(2);
sl.add(3);
sl.add(4);
sl.printList(sl.head);
sl.reverse();
sl.printList(sl.head);
}
static class Node<T> {
private T data;
private Node<T> next;
public Node(T data) {
super();
this.data = data;
}
}
}
再帰を使用するのは簡単すぎます:
package com.config;
import Java.util.Scanner;
public class Help {
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
Node head = null;
Node temp = null;
int choice = 0;
boolean flage = true;
do{
Node node = new Node();
System.out.println("Enter Node");
node.data = sc.nextInt();
if(flage){
head = node;
flage = false;
}
if(temp!=null)
temp.next = node;
temp = node;
System.out.println("Enter 0 to exit.");
choice = sc.nextInt();
}while(choice!=0);
Help.getAll(head);
Node reverse = Help.reverse(head,null);
//reverse = Help.reverse(head, null);
Help.getAll(reverse);
}
public static void getAll(Node head){
if(head==null)
return ;
System.out.println(head.data+"Memory Add "+head.hashCode());
getAll(head.next);
}
public static Node reverse(Node head,Node tail){
Node next = head.next;
head.next = tail;
return (next!=null? reverse(next,head) : head);
}
}
class Node{
int data = 0;
Node next = null;
}
/**
* Reverse LinkedList
* @author asharda
*
*/
class Node
{
int data;
Node next;
Node(int data)
{
this.data=data;
}
}
public class ReverseLinkedList {
static Node root;
Node temp=null;
public void insert(int data)
{
if(root==null)
{
root=new Node(data);
}
else
{
temp=root;
while(temp.next!=null)
{
temp=temp.next;
}
Node newNode=new Node(data);
temp.next=newNode;
}
}//end of insert
public void display(Node head)
{
while(head!=null)
{
System.out.println(head.data);
head=head.next;
}
}
public Node reverseLinkedList(Node head)
{
Node newNode;
Node tempr=null;
while(head!=null)
{
newNode=new Node(head.data);
newNode.next=tempr;
tempr=newNode;
head=head.next;
}
return tempr;
}
public static void main(String[] args) {
ReverseLinkedList r=new ReverseLinkedList();
r.insert(10);
r.insert(20);
r.insert(30);
r.display(root);
Node t=r.reverseLinkedList(root);
r.display(t);
}
}
Node Reverse(Node head) {
Node n,rev;
rev = new Node();
rev.data = head.data;
rev.next = null;
while(head.next != null){
n = new Node();
head = head.next;
n.data = head.data;
n.next = rev;
rev = n;
n=null;
}
return rev;
}
上記の関数を使用して、単一のリンクリストを逆にします。
単一リンクリストをリバースするには、3つのノードtop、beforeTop、およびAfterTopが必要です。 Topは単一リンクリストのヘッダーです。したがって、beforeTopはnullになり、afterTopはtopの次の要素になり、各反復で前方に移動します- beforeTopが割り当てられますtopおよびtopが割り当てられますafterTop(ie top .次)。
private static Node inverse(Node top) {
Node beforeTop=null, afterTop;
while(top!=null){
afterTop=top.next;
top.next=beforeTop;
beforeTop=top;
top=afterTop;
}
return beforeTop;
}
public class ReverseLinkedList {
public static void main(String args[]){
LinkedList<String> linkedList = new LinkedList<String>();
linkedList.add("a");
linkedList.add("b");
linkedList.add("c");
linkedList.add("d");
linkedList.add("e");
linkedList.add("f");
System.out.println("Original linkedList:");
for(int i = 0; i <=linkedList.size()-1; i++){
System.out.println(" - "+ linkedList.get(i));
}
LinkedList<String> reversedlinkedList = reverse(linkedList);
System.out.println("Reversed linkedList:");
for(int i = 0; i <=reversedlinkedList.size()-1; i++){
System.out.println(" - "+ reversedlinkedList.get(i));
}
}
public static LinkedList<String> reverse(LinkedList<String> linkedList){
for(int i = 0; i < linkedList.size()/2; i++){
String temp = linkedList.get(i);
linkedList.set(i, linkedList.get(linkedList.size()-1-i));
linkedList.set((linkedList.size()-1-i), temp);
}
return linkedList;
}
}
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
複雑性分析の詳細を確認してください http://javamicro.com/ref-card/DS-Algo/How-to-Reverse-Singly-Linked-List ?
package LinkedList;
import Java.util.LinkedList;
public class LinkedListNode {
private int value;
private LinkedListNode next = null;
public LinkedListNode(int i) {
this.value = i;
}
public LinkedListNode addNode(int i) {
this.next = new LinkedListNode(i);
return next;
}
public LinkedListNode getNext() {
return next;
}
@Override
public String toString() {
String restElement = value+"->";
LinkedListNode newNext = getNext();
while(newNext != null)
{restElement = restElement + newNext.value + "->";
newNext = newNext.getNext();}
restElement = restElement +newNext;
return restElement;
}
public static void main(String[] args) {
LinkedListNode headnode = new LinkedListNode(1);
headnode.addNode(2).addNode(3).addNode(4).addNode(5).addNode(6);
System.out.println(headnode);
headnode = reverse(null,headnode,headnode.getNext());
System.out.println(headnode);
}
private static LinkedListNode reverse(LinkedListNode prev, LinkedListNode current, LinkedListNode next) {
current.setNext(prev);
if(next == null)
return current;
return reverse(current,next,next.getNext());
}
private void setNext(LinkedListNode prev) {
this.next = prev;
}
}
これも試してみてください
LinkedListNode pointer = head;
LinkedListNode prev = null, curr = null;
/* Pointer variable loops through the LL */
while(pointer != null)
{
/* Proceed the pointer variable. Before that, store the current pointer. */
curr = pointer; //
pointer = pointer.next;
/* Reverse the link */
curr.next = prev;
/* Current becomes previous for the next iteration */
prev = curr;
}
System.out.println(prev.printForward());
package com.three;
public class Link {
int a;
Link Next;
public Link(int i){
a=i;
}
}
public class LinkList {
Link First = null;
public void insertFirst(int a){
Link objLink = new Link(a);
objLink.Next=First;
First = objLink;
}
public void displayLink(){
Link current = First;
while(current!=null){
System.out.println(current.a);
current = current.Next;
}
}
public void ReverseLink(){
Link current = First;
Link Previous = null;
Link temp = null;
while(current!=null){
if(current==First)
temp = current.Next;
else
temp=current.Next;
if(temp==null){
First = current;
//return;
}
current.Next=Previous;
Previous=current;
//System.out.println(Previous);
current = temp;
}
}
public static void main(String args[]){
LinkList objLinkList = new LinkList();
objLinkList.insertFirst(1);
objLinkList.insertFirst(2);
objLinkList.insertFirst(3);
objLinkList.insertFirst(4);
objLinkList.insertFirst(5);
objLinkList.insertFirst(6);
objLinkList.insertFirst(7);
objLinkList.insertFirst(8);
objLinkList.displayLink();
System.out.println("-----------------------------");
objLinkList.ReverseLink();
objLinkList.displayLink();
}
}
これを使って。
if (current== null || current.next==null) return current;
Node nextItem = current.next;
current.next = null;
Node reverseRest = reverse(nextItem);
nextItem.next = current;
return reverseRest
public static LinkedList reverseLinkedList(LinkedList node) {
if (node == null || node.getNext() == null) {
return node;
}
LinkedList remaining = reverseLinkedList(node.getNext());
node.getNext().setNext(node);
node.setNext(null);
return remaining;
}
あなたの問題は、最初の最後の要素next属性があなたの状態のために変更されていないことだと思います
if(next == null)
return;
ループの先頭にあります。
Tmp.nextが割り当てられた直後に移動します。
while(tmp != null){
tmp.next = before;
if(next == null)
return;
before = tmp;
tmp = next;
next = next.next;
}