[英]Reverse generic LinkedList by using swap method
public class SimpleLinkedList<E> {
public Node<E> head;
public int size;
public void add(E e) {
++this.size;
if (null == head) {
this.head = new Node();
head.val = e;
} else {
Node<E> newNode = new Node();
newNode.val = e;
newNode.next = head;
this.head = newNode;
}
}
public void swap(E val1, E val2) {
if (val1.equals(val2)) {
return;
}
Node prevX = null, curr1 = head;
while (curr1 != null && !curr1.val.equals(val1)) {
prevX = curr1;
curr1 = curr1.next;
}
Node prevY = null, curr2 = head;
while (curr2 != null && !curr2.val.equals(val2)) {
prevY = curr2;
curr2 = curr2.next;
}
if (curr1 == null || curr2 == null) {
return;
}
if (prevX == null) {
head = curr2;
} else {
prevX.next = curr2;
}
if (prevY == null) {
head = curr1;
} else {
prevY.next = curr1;
}
Node temp = curr1.next;
curr1.next = curr2.next;
curr2.next = temp;
}
public void reverse() {
Node<E> prev = null;
Node<E> current = head;
Node<E> next = null;
while (current != null) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
head = prev;
}
public static class Node<E> {
public Node<E> next;
public E val;
}
}
public class SimpleLinkedListTest {
@Test
public void testReverseMethod() {
SimpleLinkedList<Integer> myList = new SimpleLinkedList<>();
for (int i = 0; i < 10; i++) {
myList.add(i);
}
SimpleLinkedList<Integer> expectedList = new SimpleLinkedList<>();
for (int i = 9; i > -1; i--) {
expectedList.add(i);
}
myList.reverse();
assertTrue(AssertCustom.assertSLLEquals(expectedList, myList));
}
}
使用交換方法反轉通用 LinkedList 的最佳方法是什么? 在反向方法之前:
(head=[9])->[8]->[7]->[6]->[5]->[4]->[3]->[2]->[1]->[ 0]-> 空
在 reverse() 方法之后:
(head=[0])->[1]->[2]->[3]->[4]->[5]->[6]->[7]->[8]->[ 9]-> 空
您需要做的是將列表分成兩半。 如果列表大小為奇數,則中間的將保留在原位。 然后像時尚一樣在鏡子中交換兩側的元素。 這應該比 O(n^2) 更有效
reverse(){
Node current = this.head;
int half = this.size/2;
int midElement = this.size % 2 == 0 ? 0: half + 1;
Stack<Node<E>> stack = new Stack<Node<E>>();
for(int i = 0; i < this.size; i++){
if (i < = half)
stack.push(current);
else{
if (i == midElement)
continue;
else
swap(stack.pop(), current);
current = current.next;
}
}
swap(Node<E> v, Node<E> v1){
E tmp = v.value;
v.value = v1.value;
v1.value = tmp;
}
這是一點點偽java。 當它應該立即返回時,它仍然缺少對 size = 0 或 size = 1 的檢查。 一個 for 循環。 時間復雜度 O(n)。 還需要檢查size=2的時候,直接調用swap(...)。
基於@efekctive 的想法,有一個解決方案。 復雜度比 O^2 差一點,但不需要更改交換方法,不需要使用另一個集合。 下面的代碼通過了單元測試,但是,小心使用它,可能存在與 size/2 操作相關的錯誤。 希望這有幫助。
public void reverse() {
Node<E> current = head;
SimpleLinkedList<E> firstHalf = new SimpleLinkedList<>();
SimpleLinkedList<E> secondHalf = new SimpleLinkedList<>();
for (int i = 0; i < size; i++) {
if (i >= size / 2) {
firstHalf.add(current.val);
} else {
secondHalf.add(current.val);
}
current = current.next;
}
SimpleLinkedList<E> secondHalfReverse = new SimpleLinkedList<>();
for (int i = 0; i < secondHalf.size(); i++) {
secondHalfReverse.add(secondHalf.get(i));
}
for (int i = 0; i < size / 2; i++) {
if (secondHalfReverse.get(i) == firstHalf.get(i)) {
break;
}
swap(secondHalfReverse.get(i), firstHalf.get(i));
}
}
反轉LinkedList。
private Node reverse(Node num) {
Node currentnode = num;
Node reverseNode = null;
while(currentnode!=null){
Node temp = currentnode;
currentnode = currentnode.next;
temp.next = reverseNode;
reverseNode = temp;
}
return reverseNode;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.