赞
踩
目录
LinkedList 的底层是双向链表结构 ,由于链表没有将元素存储在连续的空间中,元素存储在单独的节点中,然后通过引用将节点连接起来了,因此在在任意位置插入或者删除元素时,不需要搬移元素,效率比较高。
- public interface SeqList<E> {
- // 尾插
- void add(E element);
- // 将 element 插入到 index 位置
- void add(int index,E element);
- // 删除 index 位置元素<返回删除的值
- E removeByIndex(int index);
- // 删除第一个值element的元素
- void removeByValue(E element);
- // 删除所有值element的元素
- void removeAllValue(E element);
- // 将下标 index 位置元素设置为 element,返回替换前的值
- E set(int index,E element);
- E get(int index);
- // 判断 o 是否在其中
- boolean contains(E element);
- int indexOf(E element);
- int size();
- void clear();
- }

定义双向链表类,实现SeqList方法,重写同String方法。
(Alt + insert 快速实现方法重写)
- package seqlist.link;
-
- import seqlist.SeqList;
-
- public class DoubleLinkedList<E> implements SeqList<E> {
- private DoubleNode head;//头节点
- private DoubleNode tail;//尾节点
-
- private int size; // 车厢节点个数,保存的元素个数
-
- //车厢类的定义,车厢作为火车的内部类,对外部完全隐藏
- private class DoubleNode {
- E val;//保存的元素
- DoubleNode prev;
- DoubleNode next;
- DoubleNode(E val) {
- this.val = val;
- }
- public DoubleNode(E val, DoubleNode prev, DoubleNode next) {
- this.val = val;
- this.prev = prev;
- this.next = next;
- }
- }
- public void addFrist(E val){ }
- @Override
- public void add(E element) { }
- @Override
- public void add(int index, E element) { }
- @Override
- public E removeByIndex(int index) { }
- @Override
- public void removeByValue(E element) { }
- @Override
- public void removeAllValue(E element) { }
- @Override
- public E set(int index, E element) { }
- public boolean rangeCheck(int index){ }
- @Override
- public E get(int index) { }
- @Override
- public boolean contains(E element) { }
- @Override
- public int indexOf(E element) { }
- @Override
- public int size() { }
- @Override
- public void clear() { }
- @Override
- public String toString() { }
- }

(1)size++
(2)如果链表为空,这个新插入的节点就是头节点
(3)链表不为空,将当前链表的尾节点的next指向新节点,新节点的前驱prev指向尾节点
(4)更新当新节点为尾节点
- public void add(E element) {
- DoubleNode node = new DoubleNode(element);
- size ++;
- if (head == null){
- head = node;
- }else {
- node.prev = tail;
- tail.next = node;
- }
- tail = node;
- }
这里头插不是重写方法!(因为前面的动态数组没又头插这一说法,所以这个方法就不放在接口里了)
(1)size++
(2)如果链表尾空,那么新节点就是头节点和尾节点
(3)链表不为空,将新节点的next指向head,head的前驱prev指向新节点
(4)更新新节点为头节点head
- public void addFirst(E element) {
- DoubleNode node = new DoubleNode(element);
- size ++;
- if(head == null){
- tail = node;
- }else {
- node.next = head;
- head.prev = node;
- }
- head = node;
- }
- private boolean rangeCheck(int index) {
- if (index < 0 ||index >= size) {
- return false;
- }
- return true;
- }
(1)判断index是否合法,不合法退出(2)判断是不是头插或者尾插,调用相应的方法添加后退出(3)调用node方法index位置节点的找到前驱prev,将prev.next作为后继节点node方法判断index是比较靠近head就从前往后遍历,比较靠近tail就从后往前遍历,使代码效率更高(4)节点链接,先连左边区域,再连右边区域(5)size++
DoubleNode node = new DoubleNode(element,prev,next);看前面的构造函数,这时候已经将node.prev = prev,node.next = next
- public void add(int index, E element) {
- if (index < 0 || index > size){
- throw new IllegalArgumentException("add index illegal");
- }
- if(head == null){
- addFirst(element);
- return;
- }
- if(index == size){
- add(element);
- return;
- }
-
- DoubleNode prev = node(index - 1);
- DoubleNode next = prev.next;
- DoubleNode node = new DoubleNode(element,prev,next);
- // 先处理左边区域
- prev.next = node;
- // 再处理右半区域
- next.prev = node;
- size ++;
- }
- // 根据传入索引与中间位置的关系,决定到底从前向后寻找节点还是从后向前寻找节点
- // 内部使用的工具方法
- private DoubleNode node(int index){
- if (index < (size>>1)){
- DoubleNode ret = head;
- for (int i = 0; i < index; i++) {
- ret = ret.next;
- }
- return ret;
- }else {
- DoubleNode ret = tail;
- for (int i = size -1; i > index; i--) {
- ret = ret.prev;
- }
- return ret;
- }
- }

(1)判断index是否合法,不合法退出
(2)调用node方法找到待删除节点
(3)调用unlink(node)方法进行删除,将node的前驱prev和后继next连接,将node的prev和next置空null,再size--。(前驱prev为空时,node是头节点,将新的头节点设为node的下一个节点next;后继next为空时node为尾节点,将node的前驱prev设尾节点)
(4)返回被删除节点的值
- public E removeByIndex(int index) {
- if (!rangeCheck(index)){
- throw new IllegalArgumentException("removeByIndex index illegal");
- }
- DoubleNode node = node(index);
- unlink(node);
- return node.val;
- }
- private void unlink(DoubleNode node){
- DoubleNode prev =node.prev;
- DoubleNode next = node.next;
- // 先处理左半区域
- if(prev == null){
- this.head = next;
- }else {
- node.next = null;
- prev.next = next;
- }
- // 在处理右半区域
- if(next == null){
- this.tail = prev;
- }else {
- node.next = null;
- next.prev = prev;
- }
- size--;
- }

遍历链表,在链表中找到与element值相等的节点,调用unlink(node)方法进行删除
- public void removeByValue(E element) {
- DoubleNode node = head;
- for (int i = 0; i < size; i++) {
- if (node.val.equals(element)){
- unlink(node);
- return;
- }
- node = node.next;
- }
- }
(1)遍历链表,在链表中找到与element值相等的节点,调用unlink(node)方法进行删除
(2)链表有多长就要遍历几次,以防有的节点没有被遍历(此时,每当进行一次删除,size就会减一,直接用size遍历可能导致某些节点漏掉了,因此用length保存初始的size值)
- public void removeAllValue(E element) {
- DoubleNode node = head;
- // 因为每次unlink之后都会修改size的值,但是删除所有元素,
- // 要把所有链表节点全部遍历一遍
- int length = this.size;
- for (int i = 0; i < length; i++) {
- DoubleNode next = node.next;
- if (node.val.equals(element)) {
- unlink(node);
- }
- node = next;
- }
- }
(1)判断index是否合法,不合法退出
(2)调用node方法找到该节点
(3)保存原来节点的值
(4)修改该节点的值
(5)返回原来节点的值
- public E set(int index, E element) {
- if(!rangeCheck(index)){
- throw new IllegalArgumentException("set index illeagal");
- }
- DoubleNode node = node(index);
- E oldVal = node.val;
- node.val = element;
- return oldVal;
- }
(1)判断index是否合法,不合法退出
(2)调用node方法找到该节点并返回
- public E get(int index) {
- if (!rangeCheck(index)) {
- throw new IllegalArgumentException("get index illegal!");
- }
- return node(index).val;
- }
- public boolean contains(E element) {
- DoubleNode node = head;
- while (node.next != null){
- if (node.val.equals(element)){
- return true;
- }
- node = node.next;
- }
- return false;
- }
- public int indexOf(E element) {
- DoubleNode node = head;
- int i = 0;
- while (node.next != null){
- if (node.val.equals(element)){
- return i;
- }
- i ++;
- node = node.next;
- }
- return -1;
- }
- public String toString() {
- StringBuilder sb = new StringBuilder();
- for(DoubleNode x = head; x != null; x = x.next){
- sb.append(x.val);
- sb.append("->");
- if(x.next == null){
- // 此时temp走到了尾结点
- sb.append("NULL");
- }
- }
- return sb.toString();
- }
- public int size() {
- return size;
- }
-
- @Override
- public void clear() {
- while (head.next != null){
- DoubleNode node = head.next;
- head.next =null;
- head.prev = null;
- head = node;
- }
- head = null;
- size = 0;
- }
- public class DoubleLinkedList<E> implements SeqList<E> {
- private DoubleNode head;//头节点
- private DoubleNode tail;//尾节点
-
- private int size; // 车厢节点个数,保存的元素个数
-
- //车厢类的定义,车厢作为火车的内部类,对外部完全隐藏
- private class DoubleNode {
- E val;//保存的元素
-
- DoubleNode prev;
- DoubleNode next;
- DoubleNode(E val) {
- this.val = val;
- }
-
- public DoubleNode(E val, DoubleNode prev, DoubleNode next) {
- this.val = val;
- this.prev = prev;
- this.next = next;
- }
- }
-
- // w尾插
- @Override
- public void add(E element) {
- DoubleNode node = new DoubleNode(element);
- size ++;
- if (head == null){
- head = node;
- }else {
- node.prev = tail;
- tail.next = node;
- }
- tail = node;
- }
- public void addFirst(E element) {
- DoubleNode node = new DoubleNode(element);
- size ++;
- if(head == null){
- tail = node;
- }else {
- node.next = head;
- head.prev = node;
- }
- head = node;
- }
-
- @Override
- public void add(int index, E element) {
- if (index < 0 || index > size){
- throw new IllegalArgumentException("add index illegal");
- }
- if(head == null){
- addFirst(element);
- return;
- }
- if(index == size){
- add(element);
- return;
- }
-
- DoubleNode prev = node(index - 1);
- DoubleNode next = prev.next;
- DoubleNode node = new DoubleNode(element,prev,next);
- // 先处理左边区域
- prev.next = node;
- // 再处理右半区域
- next.prev = node;
- size ++;
- }
- // 根据传入索引与中间位置的关系,决定到底从前向后寻找节点还是从后向前寻找节点
- // 内部使用的工具方法
- private DoubleNode node(int index){
- if (index < (size>>1)){
- DoubleNode ret = head;
- for (int i = 0; i < index; i++) {
- ret = ret.next;
- }
- return ret;
- }else {
- DoubleNode ret = tail;
- for (int i = size -1; i > index; i--) {
- ret = ret.prev;
- }
- return ret;
- }
- }
-
-
- @Override
- public E removeByIndex(int index) {
- if (!rangeCheck(index)){
- throw new IllegalArgumentException("removeByIndex index illegal");
- }
- DoubleNode node = node(index);
- unlink(node);
- return node.val;
- }
-
- @Override
- public void removeByValue(E element) {
- DoubleNode node = head;
- for (int i = 0; i < size; i++) {
- if (node.val.equals(element)){
- unlink(node);
- return;
- }
- node = node.next;
- }
- }
-
- @Override
- public void removeAllValue(E element) {
- DoubleNode node = head;
- // 因为每次unlink之后都会修改size的值,但是删除所有元素,
- // 要把所有链表节点全部遍历一遍
- int length = this.size;
- for (int i = 0; i < length; i++) {
- DoubleNode next = node.next;
- if (node.val.equals(element)) {
- unlink(node);
- }
- node = next;
- }
- }
-
- private void unlink(DoubleNode node){
- DoubleNode prev =node.prev;
- DoubleNode next = node.next;
- // 先处理左半区域
- if(prev == null){
- this.head = next;
- }else {
- node.next = null;
- prev.next = next;
- }
- // 在处理右半区域
- if(next == null){
- this.tail = prev;
- }else {
- node.next = null;
- next.prev = prev;
- }
- size--;
- }
-
- private boolean rangeCheck(int index) {
- if (index < 0 ||index >= size) {
- return false;
- }
- return true;
- }
-
- @Override
- public E set(int index, E element) {
- if(!rangeCheck(index)){
- throw new IllegalArgumentException("set index illeagal");
- }
- DoubleNode node = node(index);
- E oldVal = node.val;
- node.val = element;
- return oldVal;
- }
-
- @Override
- public E get(int index) {
- if (!rangeCheck(index)) {
- throw new IllegalArgumentException("get index illegal!");
- }
- return node(index).val;
- }
-
- @Override
- public boolean contains(E element) {
- DoubleNode node = head;
- while (node.next != null){
- if (node.val.equals(element)){
- return true;
- }
- node = node.next;
- }
- return false;
- }
-
- @Override
- public int indexOf(E element) {
- DoubleNode node = head;
- int i = 0;
- while (node.next != null){
- if (node.val.equals(element)){
- return i;
- }
- i ++;
- node = node.next;
- }
- return -1;
- }
-
- @Override
- public int size() {
- return size;
- }
-
- @Override
- public void clear() {
- while (head.next != null){
- DoubleNode node = head.next;
- head.next =null;
- head.prev = null;
- head = node;
- }
- head = null;
- size = 0;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- for(DoubleNode x = head; x != null; x = x.next){
- sb.append(x.val);
- sb.append("->");
- if(x.next == null){
- // 此时temp走到了尾结点
- sb.append("NULL");
- }
- }
- return sb.toString();
- }
- }

- public class DoubleNodeTest {
- public static void main(String[] args) {
- DoubleLinkedList<Integer> list = new DoubleLinkedList<>();
- list.add(1);
- list.add(3);
- list.add(5);
- list.add(9);
- list.add(3);
- list.add(3);
- System.out.println(list);
- System.out.println("清空链表");
- list.clear();
- System.out.println(list);
- list.add(6);
- list.add(10);
- list.add(5);
- list.add(7);
- list.add(10);
- list.add(10);
-
- System.out.println(list);
- System.out.println("------------添加测试-----------");
- System.out.println("从链表尾部添加99,头部添加99999");
- list.add(99);
- list.addFirst(99999);
- System.out.println(list.size());
- System.out.println("添加index为2,element为88");
- list.add(2,88);
- System.out.println(list);
- System.out.println(list.size());
- System.out.println("-----------删除测试------------");
- System.out.println("删除index为0");
- list.removeByIndex(0);
- System.out.println("删除元素为6");
- list.removeByValue(6);
- System.out.println("删除所有10");
- list.removeAllValue(10);
- System.out.println(list);
- System.out.println("-----------其他------------");
- System.out.println("查看是否包含10这个元素");
- System.out.println(list.contains(10));
- System.out.println("修改index为3,element为19");
- list.set(3,19);
- System.out.println("获取index为3的元素");
- System.out.println(list.get(3));
- System.out.println(list);
- System.out.println("获取element为88的index");
- System.out.println(list.indexOf(88));
- System.out.println("获取链表长度");
- System.out.println(list.size());
- System.out.println("清空链表");
- list.clear();
- System.out.println(list + "...");
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。