一、链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。
二、单链表
单链表结点的定义:
package cn.edu.scau.mk; /** * * @author MK */ 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(); } }