最近在看数据结构,看到了链表.
单向链表每个节点都有一个指向下一个元素的指针,最后一个节点的后继节点为null表示链表的结束.
链表的遍历是从表头开始,直到下个节点为空结束遍历.
放一个toString方法,演示下遍历.
@Override
public String toString() {
if (headerNode == null) {
return "[]";
} else {
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append(headerNode.element);
ListNode<E> firstNode = headerNode;
ListNode<E> iterator = firstNode.next;
while (iterator != null) {
sb.append(",").append(iterator.element);
iterator = iterator.next;
}
return sb.append("]").toString();
}
}
链表的插入分为三种情况
-
向表头插入节点
将新节点的后继节点指向原来的表头,然后将表头设置为新节点
/**
* 向表头增加元素
* @param element 需要增加的元素
*/
public void addFirst(E element) {
ListNode<E> newFirstNode = new ListNode<>(element);
newFirstNode.next = headerNode;
headerNode = newFirstNode;
}
-
向指定位置插入节点
将新节点的后继节点更新为目标节点的后继节点,然后将目标节点的后继节点更新为新节点.
/**
* 在指定元素后添加元素
*
* @param previousElement 先前的元素
* @param newElement 插入的元素
*/
public void add(E previousElement, E newElement) {
if (headerNode == null) {
throw new RuntimeException("链表中没有元素");
}
ListNode<E> firstNode = headerNode;
ListNode<E> targetNode = null;
if (firstNode.element.equals(previousElement)) {
targetNode = firstNode;
}
ListNode<E> iterator = firstNode.next;
while (iterator != null) {
if (iterator.element.equals(previousElement)) {
targetNode = iterator;
break;
}
iterator = iterator.next;
}
if (targetNode == null) {
throw new RuntimeException("链表中无法查找到指定元素所处的位置");
} else {
ListNode<E> newListNode = new ListNode<>(newElement);
newListNode.next = targetNode.next;
targetNode.next = newListNode;
}
}
-
向表尾插入节点
将表尾节点的后继节点更新为新节点,新节点的后继节点为null.
/**
* 向链表末尾添加元素
*
* @param element 需要添加的元素
*/
public void add(E element) {
if (headerNode == null) {
headerNode = new ListNode<>(element);
return;
}
//获取首节点
ListNode<E> firstNode = headerNode;
//遍历到尾节点,并将新节点的地址(指针)赋值给next
while (firstNode.next != null) {
firstNode = firstNode.next;
}
firstNode.next = new ListNode<>(element);
}
删除也分三种情况
- 删除表头
将表头元素的后继节点设置为新的表头,然后将原表头的后继节点设置为null
- 删除中间的指定位置
将指定节点的前驱节点 指向后继节点.然后指定节点的后继节点设置为null
- 删除表尾
将表尾的前驱节点的后继节点设置为null即可.
/**
* 移除链表中的某个元素
*
* @param element 需要移除的元素
*/
public boolean remove(E element) {
if (headerNode == null) {
throw new RuntimeException("链表中没有元素");
}
ListNode<E> firstNode = headerNode;
ListNode<E> iterator = firstNode.next;
if (firstNode.element.equals(element)) {
headerNode = iterator;
firstNode.next = null;
return true;
}
ListNode<E> preIterator = firstNode;
while (iterator != null) {
if (iterator.element.equals(element)) {
preIterator.next = iterator.next;
iterator.next = null;
return true;
}
preIterator = iterator;
iterator = iterator.next;
}
return false;
}
放个整体代码.
package com.relic.linkedlist;
/**
* 单向链表的简单实现
*
* @author Relic
*/
public class MyLinkedList<E> {
/**
* 链表的表头节点
*/
private ListNode<E> headerNode;
public MyLinkedList(E element) {
headerNode = new ListNode<>(element);
headerNode.next = null;
}
public MyLinkedList() {
headerNode = null;
}
public static void main(String[] args) {
MyLinkedList<String> list = new MyLinkedList<>();
list.add("test1");
list.add("test2");
list.add("test3");
list.add("test2", "test4");
list.addFirst("test0");
System.out.println(list);
System.out.println(list.indexOf(7));
System.out.println(list.lastIndexOf(2));
System.out.println(list.size());
System.out.println(list.contains("test1"));
System.out.println(list.remove("test3"));
System.out.println(list);
}
/**
* 向链表末尾添加元素
*
* @param element 需要添加的元素
*/
public void add(E element) {
if (headerNode == null) {
headerNode = new ListNode<>(element);
return;
}
//获取首节点
ListNode<E> firstNode = headerNode;
//遍历到尾节点,并将新节点的地址(指针)赋值给next
while (firstNode.next != null) {
firstNode = firstNode.next;
}
firstNode.next = new ListNode<>(element);
}
/**
* 在指定元素后添加元素
*
* @param previousElement 先前的元素
* @param newElement 插入的元素
*/
public void add(E previousElement, E newElement) {
if (headerNode == null) {
throw new RuntimeException("链表中没有元素");
}
ListNode<E> firstNode = headerNode;
ListNode<E> targetNode = null;
if (firstNode.element.equals(previousElement)) {
targetNode = firstNode;
}
ListNode<E> iterator = firstNode.next;
while (iterator != null) {
if (iterator.element.equals(previousElement)) {
targetNode = iterator;
break;
}
iterator = iterator.next;
}
if (targetNode == null) {
throw new RuntimeException("链表中无法查找到指定元素所处的位置");
} else {
ListNode<E> newListNode = new ListNode<>(newElement);
newListNode.next = targetNode.next;
targetNode.next = newListNode;
}
}
/**
* 向表头增加元素
*
* @param element 需要增加的元素
*/
public void addFirst(E element) {
ListNode<E> newFirstNode = new ListNode<>(element);
newFirstNode.next = headerNode;
headerNode = newFirstNode;
}
/**
* 移除链表中的某个元素
*
* @param element 需要移除的元素
*/
public boolean remove(E element) {
if (headerNode == null) {
throw new RuntimeException("链表中没有元素");
}
ListNode<E> firstNode = headerNode;
ListNode<E> iterator = firstNode.next;
if (firstNode.element.equals(element)) {
headerNode = iterator;
firstNode.next = null;
return true;
}
ListNode<E> preIterator = firstNode;
while (iterator != null) {
if (iterator.element.equals(element)) {
preIterator.next = iterator.next;
iterator.next = null;
return true;
}
preIterator = iterator;
iterator = iterator.next;
}
return false;
}
/**
* 返回链表中是否包括某个元素
*
* @param element 查找的元素
* @return 的布尔值
*/
public boolean contains(E element) {
ListNode<E> iterator = headerNode;
do {
if (iterator.element.equals(element)) {
return true;
}
iterator = iterator.next;
} while (iterator != null);
return false;
}
/**
* @return int 链表的长度
*/
public int size() {
int length = 0;
ListNode<E> firstNode = headerNode;
if (firstNode == null) {
return 0;
}
ListNode<E> iterator = firstNode.next;
while (iterator != null) {
length++;
iterator = iterator.next;
}
//加上首节点
return length + 1;
}
/**
* 根据角标返回链表中的元素
*
* @param index 链表中的位置
* @return 指定的元素
*/
public E indexOf(int index) {
ListNode<E> iterator = headerNode;
for (int i = 1; i < index; i++) {
if (iterator.next == null) {
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
iterator = iterator.next;
}
return iterator.element;
}
/**
* 返回从末尾开始计数指定角标的元素
*
* @param index 从末尾开始的位置
* @return 指定的元素
*/
public E lastIndexOf(int index) {
ListNode<E> pre = headerNode;
ListNode<E> later = headerNode;
//pre指针先移动index个长度
for (int i = 1; i < index; i++) {
//超出链表长度,
if (pre.next == null) {
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
pre = pre.next;
}
//同时移动两个指针,直到pre指针到达尾端,此时later指针的位置即为所求位置
while (pre.next != null) {
pre = pre.next;
later = later.next;
}
return later.element;
}
@Override
public String toString() {
if (headerNode == null) {
return "[]";
} else {
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append(headerNode.element);
ListNode<E> firstNode = headerNode;
ListNode<E> iterator = firstNode.next;
while (iterator != null) {
sb.append(",").append(iterator.element);
iterator = iterator.next;
}
return sb.append("]").toString();
}
}
static class ListNode<E> {
private E element;
private ListNode<E> next;
ListNode(E element) {
this.element = element;
next = null;
}
ListNode() {
}
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+ size();
}
}