数据结构(三)之单链表反向查找
一、反向查找单链表
1、简单查找
先遍历获取单链表单长度n,然后通过计算得到倒数第k个元素的下标为n-k,然后查找下标为n-k的元素。
2、优化查找
先找到下标为k的元素为记录点p1,然后设置新的记录点p2的下标从0开始,同时遍历两个记录点,直到p1的值为null,p2是倒数第k个元素。
单链表结点:
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; import java.util.HashMap; /** * * @author MK * @param <T> */ public class OpLinkedList<T> extends LinkedList<T> { /** * 简单反向查找 * @param index 倒数个数,从1开始 * @return */ public T getByLastIndex(int index) { //倒数个数小于1 if (index < 1) { throw new IndexOutOfBoundsException("Last Index : " + index); } int len=this.length();//链表长度 //倒数个数越界 if (head == null||len<index) { throw new IndexOutOfBoundsException("Last Index: " + index + ", Size: " + 0); } len=len-index;//第n-k个 Node<T> curNode = head; //默认第0个 for (int i = 0; i < len; i++) { curNode = curNode.getNext();//第i+1个 } return curNode.getData(); } }
三、优化查找
package cn.edu.scau.mk; import java.util.HashMap; /** * * @author MK * @param <T> */ public class OpLinkedList<T> extends LinkedList<T> { /** *优化反向查找 * @param index 倒数个数,从1开始 * @return */ public T getByLastIndex(int index) { if (index < 1) { throw new IndexOutOfBoundsException("Last Index : " + index); } if (head == null) { throw new IndexOutOfBoundsException("Last Index: " + index + ", Size: " + 0); } //查找第index个结点 Node<T> curNode = head; for (int i = 0; i < index; i++) { if (curNode==null) { throw new IndexOutOfBoundsException("Last Index: " + index + ", Size: " + i); } curNode = curNode.getNext(); } //循环直到curNode为null,indexNode刚好为倒数index个 Node<T> indexNode = head; while (curNode != null) { curNode =curNode.getNext(); indexNode=indexNode.getNext(); } return indexNode.getData(); } }