项目地址:https://gitee.com/caochenlei/data-structures
第一章 单向链表介绍
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
单向链表是链表的一种,它由多个结点组成,每个结点都由一个数据域和一个指针域组成,数据域用来存储数据, 指针域用来指向其后继结点。链表的头结点的数据域不存储数据,指针域指向第一个真正存储数据的结点。
第二章 单向链表实现
2.01、初始化链表的结构
/**
* 单向链表实现代码
*/
public class SinglyLinkedList<E> {
//定义结点类
public class Node {
E data; //代表结点数据
Node next; //指向下个结点
public Node(E data) {
this.data = data;
}
@Override
public String toString() {
return "Node{data=" + data + "}";
}
}
private Node head; //代表链表头部
private Node last; //代表链表尾部
private int size; //代表链表长度
public SinglyLinkedList() {
this.head = new Node(null);
this.last = null;
this.size = 0;
}
//请将接下来的方法书写在这里...
}
2.02、判断链表是否为空
//判断链表是否为空
public boolean isEmpty() {
return size == 0;
}
2.03、获取当前链表长度
//获取当前链表长度
public int size() {
return size;
}
2.04、连接链表两个结点
//连接链表两个结点
public void connectNode(Node prevNode, Node nextNode) {
if (prevNode != null) {
prevNode.next = nextNode;
}
}
2.05、释放链表结点指向
//释放链表结点指向
public void releaseNode(Node node) {
if (node != null) {
node.data = null;
node.next = null;
}
}
2.06、返回链表最后结点
//返回链表最后结点
public Node getLast() {
//判断链表是否为空
if (isEmpty()) {
return null;
}
//返回链表最后数据
return last;
}
2.07、返回链表首个结点
//返回链表首个结点
public Node getFirst() {
//判断链表是否为空
if (isEmpty()) {
return null;
}
//返回链表首个数据
return head.next;
}
2.08、返回指定位置结点
//返回指定位置结点
public Node getIndex(int index) {
//判断位置是否违法
if (index <= 0 || size < index) {
throw new RuntimeException("链表位置不合法!");
}
//获取指定位置结点
Node curNode = head;
for (int i = 0; i < index; i++) {
curNode = curNode.next;
}
//返回指定位置数据
return curNode;
}
2.09、链表尾后添加数据
方法实现:
//链表尾后添加数据
public void addLast(E e) {
//判断链表为空
if (isEmpty()) {
//直接往head结点后插入
last = new Node(e);
connectNode(head, last);
} else {
//直接往last结点后插入
Node oldLast = last;
last = new Node(e);
connectNode(oldLast, last);
}
//链表长度加一
size++;
}
方法测试:
public class SinglyLinkedListTest {
public static void main(String[] args) {
SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
System.out.println("===============");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.getIndex(i + 1));
}
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3
2.10、链表头后添加数据
方法实现:
//链表头后添加数据
public void addFirst(E e) {
//判断链表为空
if (isEmpty()) {
//直接往head结点后插入
last = new Node(e);
connectNode(head, last);
} else {
//获取首个结点
Node firNode = head.next;
//创建新的结点
Node newNode = new Node(e);
//两两结点连接
connectNode(head, newNode);
connectNode(newNode, firNode);
}
//链表长度加一
size++;
}
方法测试:
public class SinglyLinkedListTest {
public static void main(String[] args) {
SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();
linkedList.addFirst("张三");
linkedList.addFirst("李四");
linkedList.addFirst("王五");
System.out.println("===============");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.getIndex(i + 1));
}
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=王五}
Node{data=李四}
Node{data=张三}
===============
false
3
2.11、指定位置添加数据
方法实现:
//指定位置添加数据
public void addIndex(int index, E e) {
//寻找位置之前结点
Node preNode = getIndexPreNode(index);
//获取指定位置结点
Node curNode = preNode.next;
//创建一个新的结点
Node newNode = new Node(e);
//开始两两结点连接
connectNode(preNode, newNode);
connectNode(newNode, curNode);
//当前链表长度加一
size++;
}
//返回位置之前结点
private Node getIndexPreNode(int index) {
//判断位置是否违法
if (index <= 0 || size < index) {
throw new RuntimeException("链表位置不合法!");
}
//寻找位置之前结点
Node preNode = head;
for (int i = 0; i < index - 1; i++) {
preNode = preNode.next;
}
//返回位置之前结点
return preNode;
}
方法测试:
public class SinglyLinkedListTest {
public static void main(String[] args) {
SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
linkedList.addIndex(1, "小二");
linkedList.addIndex(4, "老六");
System.out.println("===============");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.getIndex(i + 1));
}
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=小二}
Node{data=张三}
Node{data=李四}
Node{data=老六}
Node{data=王五}
===============
false
5
2.12、删除指定位置结点
方法实现:
//删除指定位置结点
public void removeIndex(int index) {
//寻找位置之前结点
Node preNode = getIndexPreNode(index);
//获取指定位置结点
Node curNode = preNode.next;
//删除指定位置结点
preNode.next = curNode.next;
//释放当前结点指向
releaseNode(curNode);
//链表长度大小减一
size--;
}
方法测试:
public class SinglyLinkedListTest {
public static void main(String[] args) {
SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
linkedList.removeIndex(2);
System.out.println("===============");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.getIndex(i + 1));
}
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=张三}
Node{data=王五}
===============
false
2
2.13、删除链表首个结点
方法实现:
//删除链表首个结点
public void removeFirst() {
//判断链表为空
if (isEmpty()) {
return;
}
//删除首个结点
removeIndex(1);
}
方法测试:
public class SinglyLinkedListTest {
public static void main(String[] args) {
SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
linkedList.removeFirst();
linkedList.removeFirst();
System.out.println("===============");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.getIndex(i + 1));
}
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=王五}
===============
false
1
2.14、删除链表最后结点
方法实现:
//删除链表最后结点
public void removeLast() {
//判断链表为空
if (isEmpty()) {
return;
}
//删除最后结点
removeIndex(size);
}
方法测试:
public class SinglyLinkedListTest {
public static void main(String[] args) {
SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
linkedList.removeLast();
linkedList.removeLast();
System.out.println("===============");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.getIndex(i + 1));
}
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=张三}
===============
false
1
2.15、顺序输出链表内容
方法实现:
//顺序输出链表内容
public void show() {
//判断链表为空
if (isEmpty()) {
return;
}
//获取首个结点
Node curNode = head.next;
//循环往后移动
while (curNode != null) {
System.out.println(curNode);
curNode = curNode.next;
}
}
方法测试:
public class SinglyLinkedListTest {
public static void main(String[] args) {
SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
System.out.println("===============");
linkedList.show();
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3
2.16、逆序输出链表内容
方法实现:
//逆序输出链表内容
public void reverseShow() {
//判断链表为空
if (isEmpty()) {
return;
}
//递归倒序打印
reverseShow(head.next);
}
private void reverseShow(Node node) {
//判断是否结束
if (node == null) {
return;
}
//递归调用函数
reverseShow(node.next);
//打印当前结点
System.out.println(node);
}
方法测试:
public class SinglyLinkedListTest {
public static void main(String[] args) {
SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
System.out.println("===============");
linkedList.reverseShow();
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=王五}
Node{data=李四}
Node{data=张三}
===============
false
3
2.17、首尾反转当前链表
方法实现:
//首尾反转当前链表
public void reverse() {
//判断链表为空
if (isEmpty()) {
return;
}
//创建一个新头
Node newHead = new Node(null);
//获取首个结点
Node curNode = head.next;
//定义临时结点
Node tmpNode;
//循环遍历链表
while (curNode != null) {
//缓存当前结点下个结点
tmpNode = curNode.next;
//获取链表新头首个结点
Node firNode = newHead.next;
//开始结点两两连接关联
connectNode(newHead, curNode);
connectNode(curNode, firNode);
//让当前的结点往后移动
curNode = tmpNode;
}
//老头换首结点
head.next = newHead.next;
//释放新头指向
releaseNode(newHead);
}
方法测试:
public class SinglyLinkedListTest {
public static void main(String[] args) {
SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
linkedList.reverse();
System.out.println("===============");
linkedList.show();
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=王五}
Node{data=李四}
Node{data=张三}
===============
false
3
2.18、清空链表所有结点
方法实现:
//清空链表所有结点
public void clear() {
//判断链表为空
if (isEmpty()) {
return;
}
//定义当前结点
Node curNode = head;
//定义临时结点
Node tmpNode;
//重置基本变量
head = null;
last = null;
size = 0;
//循环释放结点
while (curNode != null) {
//缓存下个结点
tmpNode = curNode.next;
//释放当前结点
releaseNode(curNode);
//移动下个结点
curNode = tmpNode;
}
}
方法测试:
public class SinglyLinkedListTest {
public static void main(String[] args) {
SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
linkedList.clear();
System.out.println("===============");
linkedList.show();
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
===============
true
0
2.19、顺序查找数据首次出现位置
方法实现:
//顺序查找数据首次出现位置
public int indexOf(E e) {
//判断链表是否为空
if (isEmpty()) {
return -1;
}
//判断对象是否为空
if (e == null) {
return -1;
}
//获取指定位置结点
Node curNode = head;
for (int i = 0; curNode != null; i++) {
if (e.equals(curNode.data)) {
return i;
}
curNode = curNode.next;
}
//没有找到返回负一
return -1;
}
方法测试:
public class SinglyLinkedListTest {
public static void main(String[] args) {
SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
System.out.println(linkedList.indexOf("王五"));
System.out.println("===============");
linkedList.show();
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
3
===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3
2.20、逆序查找数据首次出现位置
方法实现:
//逆序查找数据首次出现位置
public int lastIndexOf(E e) {
//判断链表是否为空
if (isEmpty()) {
return -1;
}
//判断对象是否为空
if (e == null) {
return -1;
}
//反转当前链表结点
reverse();
//获取指定位置结点
int index = indexOf(e);
//反转当前链表结点
reverse();
//返回指定位置结果
return index;
}
方法测试:
public class SinglyLinkedListTest {
public static void main(String[] args) {
SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
System.out.println(linkedList.lastIndexOf("王五"));
System.out.println("===============");
linkedList.show();
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
1
===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3
第三章 双向链表介绍
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。链表的头结点的数据域不存储数据,指向前驱结点的指针域值为null,指向后继结点的指针域指向第一个真正存储数据结点。
第四章 双向链表实现
4.01、初始化链表的结构
/**
* 双向链表实现代码
*/
public class DoublyLinkedList<E> {
//定义结点类
public class Node {
Node prev; //指向上个结点
E data; //代表结点数据
Node next; //指向下个结点
public Node(E data) {
this.data = data;
}
@Override
public String toString() {
return "Node{data=" + data + "}";
}
}
private Node head; //代表链表头部
private Node last; //代表链表尾部
private int size; //代表链表长度
public DoublyLinkedList() {
this.head = new Node(null);
this.last = null;
this.size = 0;
}
//请将接下来的方法书写在这里...
}
4.02、判断链表是否为空
//判断链表是否为空
public boolean isEmpty() {
return size == 0;
}
4.03、获取当前链表长度
//获取当前链表长度
public int size() {
return size;
}
4.04、连接链表两个结点
//连接链表两个结点
public void connectNode(Node prevNode, Node nextNode) {
if (prevNode != null) {
prevNode.next = nextNode;
}
if (nextNode != null) {
nextNode.prev = prevNode;
}
}
4.05、释放链表结点指向
//释放链表结点指向
public void releaseNode(Node node) {
if (node != null) {
node.prev = null;
node.data = null;
node.next = null;
}
}
4.06、返回链表最后结点
//返回链表最后结点
public Node getLast() {
//判断链表是否为空
if (isEmpty()) {
return null;
}
//返回链表最后数据
return last;
}
4.07、返回链表首个结点
//返回链表首个结点
public Node getFirst() {
//判断链表是否为空
if (isEmpty()) {
return null;
}
//返回链表首个数据
return head.next;
}
4.08、返回指定位置结点
//返回指定位置结点
public Node getIndex(int index) {
//判断位置是否违法
if (index <= 0 || size < index) {
throw new RuntimeException("链表位置不合法!");
}
//获取指定位置结点
Node curNode = head;
for (int i = 0; i < index; i++) {
curNode = curNode.next;
}
//返回指定位置数据
return curNode;
}
4.09、链表尾后添加数据
方法实现:
//链表尾后添加数据
public void addLast(E e) {
//判断链表为空
if (isEmpty()) {
//直接往head结点后插入
last = new Node(e);
connectNode(head, last);
} else {
//直接往last结点后插入
Node oldLast = last;
last = new Node(e);
connectNode(oldLast, last);
}
//链表长度加一
size++;
}
方法测试:
public class DoublyLinkedListTest {
public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
System.out.println("===============");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.getIndex(i + 1));
}
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3
4.10、链表头后添加数据
方法实现:
//链表头后添加数据
public void addFirst(E e) {
//判断链表为空
if (isEmpty()) {
//直接往head结点后插入
last = new Node(e);
connectNode(head, last);
} else {
//获取首个结点
Node firNode = head.next;
//创建新的结点
Node newNode = new Node(e);
//两两结点连接
connectNode(head, newNode);
connectNode(newNode, firNode);
}
//链表长度加一
size++;
}
方法测试:
public class DoublyLinkedListTest {
public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();
linkedList.addFirst("张三");
linkedList.addFirst("李四");
linkedList.addFirst("王五");
System.out.println("===============");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.getIndex(i + 1));
}
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=王五}
Node{data=李四}
Node{data=张三}
===============
false
3
4.11、指定位置添加数据
方法实现:
//指定位置添加数据
public void addIndex(int index, E e) {
//获取指定位置结点
Node curNode = getIndex(index);
//指定位置前个结点
Node prevNode = curNode.prev;
//创建一个新的结点
Node newNode = new Node(e);
//开始两两结点连接
connectNode(prevNode, newNode);
connectNode(newNode, curNode);
//当前链表长度加一
size++;
}
方法测试:
public class DoublyLinkedListTest {
public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
linkedList.addIndex(1, "小二");
linkedList.addIndex(4, "老六");
System.out.println("===============");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.getIndex(i + 1));
}
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=小二}
Node{data=张三}
Node{data=李四}
Node{data=老六}
Node{data=王五}
===============
false
5
4.12、删除链表最后结点
方法实现:
//删除链表最后结点
public void removeLast() {
//判断链表是否为空
if (isEmpty()) {
return;
}
//获取链表最后节点
Node lastNode = last;
//删除链表最后结点
Node prevNode = lastNode.prev;
prevNode.next = null;
//释放最后节点指向
releaseNode(lastNode);
//修改last的指向
last = prevNode;
//让链表的长度减一
size--;
}
方法测试:
public class DoublyLinkedListTest {
public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
linkedList.removeLast();
linkedList.removeLast();
System.out.println("===============");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.getIndex(i + 1));
}
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=张三}
===============
false
1
4.13、删除链表首个结点
方法实现:
//删除链表首个结点
public void removeFirst() {
//判断链表是否为空
if (isEmpty()) {
return;
}
//获取链表首个结点
Node firsNode = head.next;
//删除链表首个结点
Node nextNode = firsNode.next;
connectNode(head, nextNode);
//释放首个结点指向
releaseNode(firsNode);
//修改last的指向
last = nextNode;
//让链表的长度减一
size--;
}
方法测试:
public class DoublyLinkedListTest {
public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
linkedList.removeFirst();
linkedList.removeFirst();
System.out.println("===============");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.getIndex(i + 1));
}
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=王五}
===============
false
1
4.14、删除指定位置结点
方法实现:
//删除指定位置结点
public void removeIndex(int index) {
//获取指定位置结点
Node curNode = getIndex(index);
//指定位置前个结点
Node prevNode = curNode.prev;
//指定位置后个结点
Node nextNode = curNode.next;
//开始两两结点连接
connectNode(prevNode, nextNode);
//释放当前结点指向
releaseNode(curNode);
//当前链表长度减一
size--;
}
方法测试:
public class DoublyLinkedListTest {
public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
linkedList.removeIndex(2);
System.out.println("===============");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.getIndex(i + 1));
}
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=张三}
Node{data=王五}
===============
false
2
4.15、顺序输出链表内容
方法实现:
//顺序输出链表内容
public void show() {
//判断链表为空
if (isEmpty()) {
return;
}
//获取首个结点
Node curNode = head.next;
//循环往后移动
while (curNode != null) {
System.out.println(curNode);
curNode = curNode.next;
}
}
方法测试:
public class DoublyLinkedListTest {
public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
System.out.println("===============");
linkedList.show();
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3
4.16、逆序输出链表内容
方法实现:
//逆序输出链表内容
public void reverseShow() {
//判断链表为空
if (isEmpty()) {
return;
}
//获取最后结点
Node curNode = last;
//循环往前移动
while (curNode.prev != null) {
System.out.println(curNode);
curNode = curNode.prev;
}
}
方法测试:
public class DoublyLinkedListTest {
public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
System.out.println("===============");
linkedList.reverseShow();
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=王五}
Node{data=李四}
Node{data=张三}
===============
false
3
4.17、首尾反转当前链表
方法实现:
//首尾反转当前链表
public void reverse() {
//判断链表为空
if (isEmpty()) {
return;
}
//创建一个新头
Node newHead = new Node(null);
//获取首个结点
Node curNode = head.next;
//定义临时结点
Node tmpNode;
//循环遍历链表
while (curNode != null) {
//缓存当前结点下个结点
tmpNode = curNode.next;
//获取链表新头首个结点
Node firNode = newHead.next;
//开始结点两两连接关联
connectNode(newHead, curNode);
connectNode(curNode, firNode);
//让当前的结点往后移动
curNode = tmpNode;
}
//老头换首结点
head.next = newHead.next;
//释放新头指向
releaseNode(newHead);
}
方法测试:
public class DoublyLinkedListTest {
public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
linkedList.reverse();
System.out.println("===============");
linkedList.show();
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
Node{data=王五}
Node{data=李四}
Node{data=张三}
===============
false
3
4.18、清空链表所有结点
方法实现:
//清空链表所有结点
public void clear() {
//判断链表为空
if (isEmpty()) {
return;
}
//定义当前结点
Node curNode = head;
//定义临时结点
Node tmpNode;
//重置基本变量
head = null;
last = null;
size = 0;
//循环释放结点
while (curNode != null) {
//缓存下个结点
tmpNode = curNode.next;
//释放当前结点
releaseNode(curNode);
//移动下个结点
curNode = tmpNode;
}
}
方法测试:
public class DoublyLinkedListTest {
public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
linkedList.clear();
System.out.println("===============");
linkedList.show();
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
===============
===============
true
0
4.19、顺序查找数据首次出现位置
方法实现:
//顺序查找数据首次出现位置
public int indexOf(E e) {
//判断链表是否为空
if (isEmpty()) {
return -1;
}
//判断对象是否为空
if (e == null) {
return -1;
}
//获取指定位置结点
Node curNode = head;
for (int i = 0; curNode != null; i++) {
if (e.equals(curNode.data)) {
return i;
}
curNode = curNode.next;
}
//没有找到返回负一
return -1;
}
方法测试:
public class DoublyLinkedListTest {
public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
System.out.println(linkedList.indexOf("王五"));
System.out.println("===============");
linkedList.show();
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
3
===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3
4.20、逆序查找数据首次出现位置
方法实现:
//逆序查找数据首次出现位置
public int lastIndexOf(E e) {
//判断链表是否为空
if (isEmpty()) {
return -1;
}
//判断对象是否为空
if (e == null) {
return -1;
}
//获取指定位置结点
Node curNode = last;
for (int i = 1; curNode != null; i++) {
if (e.equals(curNode.data)) {
return i;
}
curNode = curNode.prev;
}
//没有找到返回负一
return -1;
}
方法测试:
public class DoublyLinkedListTest {
public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();
linkedList.addLast("张三");
linkedList.addLast("李四");
linkedList.addLast("王五");
System.out.println(linkedList.lastIndexOf("王五"));
System.out.println("===============");
linkedList.show();
System.out.println("===============");
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.size());
}
}
运行结果:
1
===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3