采用双向链表的形式尝试写一下 java中LinkedList
public class LinkedList<E> {
/**
* 节点
*/
private static class Node<E> {
E item;
Node<E> pre;
Node<E> next;
public Node(Node<E> pre, E item, Node<E> next) {
this.item = item;
this.pre = pre;
this.next = next;
}
}
public LinkedList() {
}
//头节点
Node<E> first;
//尾节点
Node<E> last;
//大小
int size;
/**
* 添加数据在最后
*/
public void add(E e) {
linkLast(e);
}
/**
* 添加到最后
*
* @param e
*/
private void linkLast(E e) {
Node<E> newNode = new Node<>(last, e, null);
Node<E> temp = last;
last = newNode;
if (temp == null) {
first = newNode;
} else {
temp.next = newNode;
}
size++;
}
/**
* 获取对象
*/
public E get(int index) {
if (index < 0 || index > size - 1) {
return null;
}
return node(index).item;
}
/**
* 获取index位置上的节点
*
* @param index
*/
private Node<E> node(int index) {
Node<E> node;
//如果index在链表前半部分
if (index < (size >> 1))//除以2
{
node = first;
for (int i = 0; i < index; i++) {
node = node.next;
}
} else {
node = last;
for (int i = size - 1; i > index; i--) {
node = node.pre;
}
}
return node;
}
/**
* 添加数据在index位置
*/
public void add(int index, E e) {
if (index < 0 || index > size) {
return;
}
if (index == size) {
linkLast(e);
} else {
Node<E> target = node(index);
Node<E> preNode = target.pre;
Node<E> newNode = new Node<>(preNode, e, target);
if (preNode == null) {
first = newNode;
target.pre = newNode;
} else {
preNode.next = newNode;
target.pre = newNode;
}
size++;
}
}
/**
* 删除元素
*/
public void remove(int index) {
if (size == 0 || index < 0 || index > size - 1) {
return;
}
Node<E> node = node(index);
unLinkNode(node);
}
private void unLinkNode(Node<E> node) {
Node<E> preNode = node.pre;
Node<E> nextNode = node.next;
if (preNode == null) {
first = nextNode;
} else if (nextNode == null) {
last = preNode;
} else {
preNode.next = nextNode;
nextNode.pre = preNode;
}
size--;
}
}
写个test测试下功能
@Test
public void testLinkedList(){
LinkedList<Integer> list=new LinkedList<>();
list.add(3);
list.add(80);
list.add(1);
list.add(7);
list.add(32);
log(list);
list.add(0,12);
log(list);
list.add(3,50);
log(list);
list.remove(3);
log(list);
list.remove(0);
log(list);
}
public void log(LinkedList linkedList){
for (int i = 0; i < linkedList.size; i++) {
System.out.print(linkedList.get(i)+" ");
}
System.out.println("");
}
打印结果
3 80 1 7 32
12 3 80 1 7 32
12 3 80 50 1 7 32
12 3 80 1 7 32
3 80 1 7 32
判断单链表是否存在环?
【快慢指针】:需要两个指针,一个快指针:每次走两步,一个慢指针:每次走一步。
如果快慢指针能够相遇(如果快指针能够追上慢指针),就证明有环。
但是!!!这个方法存在问题。如果链表够长,而环又足够小,那么快指针将永远不会追上慢指针
所以,快慢指针只适合用于环出现在链表尾部的情况,也就是单链表环的问题,而无法解决链表存在循环的问题。
public class Link_list_circle {
public boolean hascycle(ListNode head) {
//快慢指针
ListNode slow, fast;
slow = fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (fast == slow) return ture;
}
return false;
}
}