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));
}
}
使用swap方法反转泛型LinkedList的最佳方法是什么? 在反向方法之前:
(头= [9]) - &GT; [8] - &GT; [7] - &GT; [6] - &GT; [5] - &GT; [4] - &GT; [3] - &GT; [ 2] - &GT; [1] - &GT; [0] - &GT;空
在reverse()方法之后:
(头= [0]) - &GT; [1] - &GT; [2] - &GT; [3] - &GT; [4] - &GT; [5] - &GT; [6] - &GT; [ 7] - GT; [8] - &GT; [9] - &GT;空
答案 0 :(得分:1)
您需要做的是将列表分成两半。如果列表大小为奇数,则中间的大小将保持不变。然后像时尚一样在镜子的两边交换元素。这应该比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的检查。一个循环。时间复杂度O(n)。还需要检查size = 2,直接调用swap(...)。
答案 1 :(得分:0)
根据@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));
}
}
答案 2 :(得分:-1)
反向链接列表。
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;
}