package com.zjp.structures; /** * 带头节点(不带数据)的双链表 */ public class DoubleLinkedList<T> { DNode<T> head; DNode<T> tail; public DoubleLinkedList() { //初始化头节点 this.head = this.tail = new DNode<T>(); } /** * 传入一个数组,转换成一个链表 * * @param arr */ public DoubleLinkedList(T[] arr) { this(); if (arr != null && arr.length > 0) { head.next = new DNode<T>(arr[0]); tail = head.next; tail.prev = head; int j = 1; while (j < arr.length) { tail.next = new DNode<T>(arr[j++]); tail.next.prev = tail; tail = tail.next; } } } /** * 插入节点 * * @param index * @param data * @return */ public boolean add(int index, T data) { if (index < 0 || data == null) { throw new NullPointerException("index<0||data == null"); } //查找要插入节点位置的前一个节点 int j = 0; DNode front = this.head; while (j < index && front.next != null) { j++; front = front.next; } //创建需要插入的节点,让其前一个节点指向front,后一个节点指向front.next DNode<T> q = new DNode<T>(data, front, front.next); //空双链表插入和尾部插入,无需次操作 if (front.next != null) { //更改front.next的前几指针 front.next.prev = q; } //更改front的后继指针 front.next = q; //在尾部插入时需要更改tail指向 if (front == this.tail) { this.tail = q; } return true; } /** * 尾部添加 * * @param data * @return */ public boolean add(T data) { if (data == null) { return false; } //创建要插入的节点 DNode<T> p = new DNode<T>(data, tail, null); tail.next = p; tail = p; return true; } /** * 根据下标删除节点 * 1,头删除 * 2,中间删除 * 3,尾部删除,更新tail指向 * * @param index * @return */ public T remove(int index) { int size = length(); T temp = null; if (index < 0 || index >= size || isEmpty()) { return temp; } //寻找要删除的节点 DNode<T> p = this.head; int j = 0; while (j <= index && p != null) { p = p.next; j++; } //更新后继节点,当双链表只有一个节点或者在尾部删除时,无需此操作 if (p.next != null) { p.next.prev = p.prev; } //更新前驱节点 p.prev.next = p.next; //如果删除的是尾节点,更新尾节点的指向 if (p == tail) { this.tail = p.prev; } temp = p.data; return temp; } /** * 根据data删除节点 * * @param data * @return */ public boolean removeAll(T data) { boolean isRemove = false; if (data == null) { return isRemove; } //起始节点 DNode p = this.head.next; while (p != null) { if (p.data.equals(data)) { //如果是尾节点 if (p == tail) { //更新尾节点的指向 tail = p.prev; p.prev = null; tail.next = null; } else {//如果不是尾节点 p.next.prev = p.prev; p.prev.next = p.next; } isRemove = true; } //继续查找 p = p.next; } return isRemove; } /** * 求双链表的长度 * * @return */ public int length() { int length = 0; DNode pre = head.next; while (pre != null) { pre = pre.next; length++; } return length; } /** * 判断双链表是否为空 * * @return */ public boolean isEmpty() { return head.next == null; } /** * 双链表的查值操作 * * @param index * @return */ public T get(int index) { if (index >= 0) { //起始节点 DNode<T> p = this.head.next; int i = 0; //查找节点 while (i < index && p != null) { i++; p = p.next; } if (p != null) { return p.data; } } return null; } /** * 双链表的替换值操作 * * @param index * @param data * @return */ public T set(int index, T data) { T old = null; if (index >= 0 && data != null) { DNode<T> p = this.head.next; int j = 0; //寻找要替换的节点 while (j < index && p != null) { j++; p = p.next; } if (p != null) { old = p.data; //替换数据 p.data = data; } } return old; } /** * 清空链表 */ public void clear() { this.head.next = null; this.tail = this.head; } public boolean contains(T data) { if (data == null) { return false; } DNode p = head.next; while (p != null) { if (p.data.equals(data)) { return true; } else { p = p.next; } } return false; } @Override public String toString() { String s = "{"; //起始节点 DNode p = head.next; while (p != null) { s += p.data; p = p.next; if (p != null) { s += ","; } } return s + "}"; } //测试方法 public static void main(String[] args) { String[] arr = {"A", "B", "C", "D", "E", "F"}; DoubleLinkedList<String> doubleLinkedList = new DoubleLinkedList<String>(arr); boolean a = doubleLinkedList.contains("A"); System.out.println(a); doubleLinkedList.remove(0); boolean a1 = doubleLinkedList.contains("A"); System.out.println(a1); System.out.println(doubleLinkedList.length()); doubleLinkedList.set(3, "D"); System.out.println(doubleLinkedList.get(2)); System.out.println(doubleLinkedList.toString()); boolean a2 = doubleLinkedList.removeAll("D"); System.out.println(a2); System.out.println(doubleLinkedList.toString()); doubleLinkedList.clear(); System.out.println(doubleLinkedList.toString()); } class DNode<T> { //数据域 T data; //前驱节点 DNode prev; //后继节点 DNode next; public DNode(T data, DNode prev, DNode next) { this.data = data; this.prev = prev; this.next = next; } public DNode() { this(null, null, null); } public DNode(T data) { this(data, null, null); } @Override public String toString() { return this.data.toString(); } } }
java数据结构--双链表的设计与实现
最新推荐文章于 2023-08-01 17:33:40 发布