一、查找单链表中间结点
1、简单查找
先遍历获取单链表单长度n,然后通过计算得到中间结点为n/2,然后查找下标为n/2的元素。
2、优化查找
先设置记录点fast、slow,下标均从0开始,fast走两步,slow走一步,同时遍历两个记录点,直到fast的值为null,slow是中间结点。
单链表结点:
package cn.edu.scau.mk; /** * * @author MK * @param <T> */ public class Node<T> { private T data; private Node<T> next = null; public Node(T data) { this.data = data; } public T getData() { return data; } public void setData(T data) { this.data = data; } public Node<T> getNext() { return next; } public void setNext(Node<T> next) { this.next = next; } }
链表:
package cn.edu.scau.mk; import java.util.Comparator; /** * * @author MK * @param <T> */ public class LinkedList<T> { protected Node<T> head = null; /** * 添加 * * @param data */ public void add(T data) { //头结点为null if (head == null) { head = new Node<>(data); return; } //寻找末结点 Node<T> curNode = head; while (curNode.getNext() != null) { curNode = curNode.getNext(); } curNode.setNext(new Node<>(data));//添加结点 } /** * 删除 * * @param index 下标,从0开始 * @return */ public boolean delete(int index) { //没有数据 if (head == null) { return false; } //删除头结点 if (index == 0) { head = head.getNext(); } Node<T> curNode = head; int i = 1; while (curNode.getNext() != null) { if (i == index) { curNode.setNext(curNode.getNext().getNext()); return true; } i++; curNode = curNode.getNext(); } throw new IndexOutOfBoundsException("Index: "+index+", Size: "+i); } /** * 长度 * * @return */ public int length() { int len = 0; Node<T> curNode = head; while (curNode != null) { len++; curNode = curNode.getNext(); } return len; } /** * 查找 * @param index 位置 * @return */ public T get(int index) { Node<T> curNode = head; int i = 0; while (curNode != null) { if (i == index) { return curNode.getData(); } i++; curNode = curNode.getNext(); } throw new IndexOutOfBoundsException("Index: "+index+", Size: "+i); } /** * 排序 * @param comparator 比较器 */ public void sort(Comparator<T> comparator) { //没有数据 if (head == null) { return; } Node<T> curNode = head; Node<T> nextNode; Node<T> minNode; while (curNode.getNext() != null) { minNode = curNode; //默认最小结点为当前结点 nextNode = curNode.getNext(); //下一个结点 while (nextNode != null) { //比当前结点小,记录最小结点 if(comparator.compare(curNode.getData(), nextNode.getData())>0){ minNode=nextNode; } nextNode=nextNode.getNext(); //继续与下一个结点比较 } //最小结点不是当前结点,交换数据 if(minNode!=curNode){ T data=curNode.getData(); curNode.setData(minNode.getData()); minNode.setData(data); } curNode=curNode.getNext(); //移至下一个结点 } } /** * 打印输出 */ public void print() { Node<T> curNode = head; while (curNode!=null) { System.out.print(curNode.getData()+" "); curNode=curNode.getNext(); } System.out.println(); } }
二、简单查找
package cn.edu.scau.mk; /** * * @author MK * @param <T> */ public class MidLinkedList<T> extends LinkedList<T> { /** * 获取中间结点 * * @return */ public T getMid() { if (head == null) { throw new NullPointerException("no middle element"); } Node<T> curNode = head; int len=length()/2; for (int i = 0; i <len ; i++) { curNode=curNode.getNext(); } return curNode.getData(); } }
三、优化查找
package cn.edu.scau.mk; /** * * @author MK * @param <T> */ public class MidLinkedList<T> extends LinkedList<T> { /** * 获取中间结点 * * @return */ public T getMid() { //没有数据 if (head == null) { throw new NullPointerException("no middle element"); } Node<T> fast = head; Node<T> slow = head; while (fast != null && fast.getNext() != null) { fast = fast.getNext().getNext();//快记录点走两步 slow = slow.getNext(); //慢记录点走一步 } return slow.getData(); } }