习题3.2:通过只调整链(而不是数据)来交换两个相邻的元素,使用 a. 单链表 b.双链表
单链表:
public class SingleNode {
private String data;
private SingleNode next;
public SingleNode(String datat) {
this.data = datat;
this.next = null;
}
public void addNode(SingleNode node) {
this.next = node;
}
/**
* traverse the position of two data
*
* @param data1
*/
public static void traverse(String data1, SingleNode node) {
if (node.data.equals(data1)) { // first one is the target node
//then data2 is its next node
SingleNode data2Node = node.next; // data1's next node = data2
//begin traverse
//(1) exchange the value
node.data = data2Node.data;
data2Node.data = data1;
} else {
while (node.next != null) {
if (node.next.data.equals(data1) && node.next.next != null) {
//then data2 is its next node
SingleNode node1 = node.next; // node.next = node1;
SingleNode node2 = node.next.next;// node.next.next = node2;
SingleNode node3 = node.next.next.next; // node2.next
//begin exchange
//(1) node.next = node2;
node.next = node2;
//(2) node2.next = node1;
node2.next = node1;
//(3) node1.next = node3;
node1.next = node3;
//finish
break;
} else {
//next
node = node.next;
}
}
}
}
public static void println(SingleNode singleNode) {
SingleNode first = singleNode.next; // the first node
System.out.print(singleNode.data);
while (first != null) {
System.out.print(first.data);
first = first.next;
}
}
}
复制代码
测试代码:
SingleNode n1 = new SingleNode("111");
SingleNode n2 = new SingleNode("222");
SingleNode n3 = new SingleNode("333");
SingleNode n4 = new SingleNode("444");
SingleNode n5 = new SingleNode("555");
n1.addNode(n2); ;
n2.addNode(n3);
n3.addNode(n4);
n4.addNode(n5);
SingleNode.traverse("333",n1);
SingleNode.println(n1);
复制代码
双链表:
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Spliterator;
import java.util.function.Consumer;
public class MyLinkedList<AnyType> implements Iterable<AnyType> {
private int thesize;
public static class Node<AnyType> {
public Node(AnyType data, Node<AnyType> prev, Node<AnyType> next) {
this.data = data;
this.prev = prev;
this.next = next;
}
public AnyType data;
public Node<AnyType> prev;
public Node<AnyType> next;
}
public MyLinkedList() {
clear();
}
public void clear() {
beginMarker = new Node<AnyType>(null, null, null);
endMarker = new Node<AnyType>(null, beginMarker, null);
beginMarker.next = endMarker;
thesize = 0;
modCount++;
}
public int size() {
return thesize;
}
public boolean isEmpty() {
return size() == 0;
}
public boolean add(AnyType x) {
add(size(), x);
return true;
}
public void add(int idx, AnyType x) {
addBefore(getNode(idx), x);
}
public AnyType get(int idx) {
return getNode(idx).data;
}
public AnyType set(int idx, AnyType newVal) {
Node<AnyType> p = getNode(idx);
AnyType oldVal = p.data;
p.data = newVal;
return oldVal;
}
public AnyType remove(int idx) {
return remove(getNode(idx));
}
private void addBefore(Node<AnyType> p, AnyType x) {
Node<AnyType> newNode = new Node<AnyType>(x, p.prev, p);
newNode.prev.next = newNode;
p.prev = newNode;
thesize++;
modCount++;
}
private AnyType remove(Node<AnyType> p) {
p.prev.next = p.next;
p.next.prev = p.prev;
thesize--;
modCount++;
return p.data;
}
private Node<AnyType> getNode(int idx) {
Node<AnyType> p;
if (idx < 0 || idx > thesize) {
throw new IndexOutOfBoundsException();
}
if (idx < thesize / 2) {
p = beginMarker.next;
for (int i = 0; i < idx; i++) {
p = p.next;
}
} else {
p = endMarker;
for (int i = thesize; i > idx; i--) {
p = p.prev;
}
}
return p;
}
@Override
public Iterator<AnyType> iterator() {
return new LinkedListIteractor();
}
private class LinkedListIteractor implements Iterator<AnyType> {
private Node<AnyType> current = beginMarker.next;
private int expectedModCount = modCount;
private boolean okToRemove = false;
@Override
public boolean hasNext() {
return current != endMarker;
}
@Override
public AnyType next() {
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
if (!hasNext()) {
throw new NoSuchElementException();
}
AnyType nextItem = current.data;
current = current.next;
okToRemove = true;
return nextItem;
}
public void remove() {
if (modCount != expectedModCount) { //when it called add() method with next() method, this happen
throw new ConcurrentModificationException();
}
if (!okToRemove) {
throw new IllegalStateException();
}
MyLinkedList.this.remove(current.prev);
okToRemove = false;
expectedModCount++;
}
}
/**
* traverse the position between data1 and its next data
*
* @param data1
*/
public void traverse(AnyType data1) {
for (int i = 0; i < thesize; i++) {
Node<AnyType> node = getNode(i);
if (node.data.equals(data1) && node.next.data != null) {
Node<AnyType> next = node.next;
next.prev = node.prev;
next.next.prev = node;
node.next = next.next;
next.next = node;
node.prev.next = next;
node.prev = next;
break;
}
}
}
public void print(){
for (int i=0 ; i < thesize ; i ++){
AnyType anyType = get(i);
System.out.print(anyType);
}
}
private int modCount = 0;
private Node<AnyType> beginMarker;
private Node<AnyType> endMarker;
}
复制代码
测试代码:
MyLinkedList<String> list = new MyLinkedList<>();
list.add("111");
list.add("222");
list.add("333");
list.add("444");
list.traverse("111");
list.print();
复制代码