1.链表编写
/**ILink是定义的链表操作标准接口*/
public class LinkList<E> implements ILink<E> {
private Node sentry; //哨兵节点
private Node rear; //尾节点
private int size; //链表元素个数
private int index; //遍历的指针
/*内部类**/
private class Node{
private E data;
private Node next;
public Node(E data){
this(data,null);
}
public Node(E data,Node next){
this.data = data;
this.next = next;
}
}
public LinkList(){
sentry = new Node(null);
this.rear = this.sentry;
}
//省略新增等基本操作
}
2.单链表反转实现
2.1 迭代反转链表
解释:定义三个指针,遍历节点的过程中改变节点指向即可(mid指针),移动指针的顺序分别是beg,mid,end
/**
* 单链表反转操作-迭代反转链表
* @return
*/
public void reverse() {
Node beg = null;
Node mid = this.sentry;
Node end = mid.next;
while(true){
if(end == null){
break;
}
mid.next = beg;
beg = mid;
mid = end;
end = end.next;
}
mid.next = beg;
this.sentry = mid;
TraversalRev(this.sentry);
}
/**递归遍历*/
public void TraversalRev(Node node){
System.out.println(node.data);
if(node.next == null){
return;
}else{
TraversalRev(node.next);
}
}
2.2 头插法反转链表
解释:跟入栈的思想一致,注意指针丢失
public void reverse2(){
Node newHead = null;
Node nextNode = this.sentry.next;
while(true) {
if (nextNode == null) {
break;
} else {
//先取接下来的节点
Node temp = nextNode.next;
//让新的头结点连到上一个点
nextNode.next = newHead;
//将新头结点指针指向新头结点
newHead = nextNode;
//继续遍历下来的点
nextNode = temp;
}
}
this.sentry.next = newHead;
}
3.链表中环的检测
3.1 链表中环的检测本质是判断存储指针的部分是否有重复即可
/**
* 同一个节点会不会被多个节点的next所存储
* 遍历所有节点,设置一个Set,将存储的节点地址存入,如果重复就有环
* @return
*/
@Override
public boolean isLoop() {
Set<Node> nodeSet = new HashSet<>();
Node node = this.sentry;
while (node != null){
//存在返回false
if(!nodeSet.add(node.next)){
return true;
}
node = node.next;
}
return false;
}
3.2 龟兔赛跑算法-即快慢指针,如果链表中存在环,二者一定会在某一时刻相遇
/**
* 快慢指针,如果没有环 二者不会相遇
* @return
*/
@Override
public boolean isLoop2() {
Node slow = this.sentry;
Node fast = this.sentry;
while(fast != null || fast.next != null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast){
return true;
}
}
return false;
}