数据结构-单向链表实现
目录
从上海到北京的高铁一路可能要经过苏州/无锡/常州/济南/天津/北京,如果将每个连接使用一个指向连接起来,可以形成一个链,这样就可以知道某个站的下一个站是哪个。
单向链表
每个站点抽象为一个节点,在每个节点中记录下一个站的名称,从而串成链条,这样的数据结构称为单向链表。其中指向称为指针域,指针域指向的节点称为后继节点。
Class SingleLinkedList<E>
属性概述
作用域和类型 | 属性和描述 | 备注 |
---|---|---|
private final Node | head 标识链表头位置 |
该属性默认一个空值节点,前驱为空,后驱为链表第一个有效节点 |
private int | size 记录链表长度 |
添加节点 +1 删除节点 -1 |
static final class | Node 内部节点类 |
拥有 next 指针域和 data 数据域 |
方法概述
作用域和类型 | 函数和描述 | 备注 |
---|---|---|
public void | add(E data) 添加新值到链表 |
该节点在链表末尾添加 |
public Object | delete(int index) 删除指定位置节点且返回节点 |
遍历到 index 位置删除 |
public void | insert(int index, E data) 添加新值到链表指定位置 |
遍历到 index 位置删除 |
public int | getSize() 获取链表的长度 |
返回属性 size 当前值 |
public Object | getData(int index) 获取链表指定位置的值 |
|
public void | print() 打印链表 |
用于调试 |
public boolean | isEmpty() 判断链表为空 |
|
public void clear() | clear() 清空链表数据部分 |
保留了头部节点 |
关键操作步骤
链表末尾添加元素
链表末尾添加元素,一般使用遍历方法寻找到最后一个节点,默认最有一个节点的 next 指向为空
第一步:使用遍历方法寻找到最后一个节点 lastNode ;
第二步:将 lastNode 的 next 指针域指向 newNode;将 newNode 作为 lastNode 的下一个节点;
public void add(E data) {
Node newNode = new Node(data);
Node lastNode = head;
while (lastNode.next != null) {
lastNode = lastNode.next;
}
lastNode.next = newNode;
size++;
}
删除指定下标的元素
删除指定下标的元素,采用遍历寻找方式找到指定下标元素的前一个节点,将该节点和删除节点的指向切断直接指向删除节点的下一个节点。
第一步:使用遍历方法寻找到最后一个节点 preNode ;
第二步:获取 preNode 的下一个节点即 delNode ;
第三步:获取 preNode 的下一个节点直接指向 delNode的下一个节点 ;
public Object delete(int index) {
Node preNode = head;
if (index > getSize()) return null;
for (int i = 1; i < index; i++) {
preNode = preNode.next;
}
Node delNode = preNode.next;
preNode.next = delNode.next;
size--;
return delNode;
}
向指定下标的添加元素
向指定下标的添加元素,采用遍历方式寻找该下标对应的节点的上一个节点 prevNode,在 prevNode 和其后继节点 successorNode 之间插入 newNode。步骤如下:
第一步:获取该删除节点的后继节点 successorNode;
第二步:将 prevNode 的 next 指针域指向 newNode;
第三步:将 newNode 的 next 指针域指向 successorNode;
public void insert(int index, E data) {
Node newNode = new Node(data);
Node preNode = head;
if (index > getSize()) return;
for (int i = 1; i < index; i++) {
preNode = preNode.next;
}
Node successor = preNode.next;
preNode.next = newNode;
newNode.next = successor;
size++;
}
编码实现
interface LinkedList<E>
package com.skystep.数据结构和算法.链表.双向链表;
public interface LinkedList<E> {
//在链表尾部增加数据
void add(E data);
//删除指定位置的节点
Object delete(int index);
//在指定索引处插入节点
void insert(int index, E data);
//获取链表长度;
int getSize();
//获取某个索引数据
Object getData(int index);
void print();
//是否空
boolean isEmpty();
// 清空链表
void clear();
}
class SingleLinkedList<E>
package com.skystep.数据结构和算法.链表.单向链表;
public class SingleLinkedList<E> implements LinkedList<E> {
Node head = new Node();
int size = 0;
static final class Node<E> {
private Node next = null;
private E data = null;
public Node() {
}
public Node(E data) {
this.data = data;
}
public Node(Node next, E data) {
this.next = next;
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
}
@Override
public void add(E data) {
Node newNode = new Node(data);
Node lastNode = head;
while (lastNode.next != null) {
lastNode = lastNode.next;
}
lastNode.next = newNode;
size++;
}
@Override
public Object delete(int index) {
Node preNode = head;
if (index > getSize()) return null;
for (int i = 1; i < index; i++) {
preNode = preNode.next;
}
Node delNode = preNode.next;
preNode.next = delNode.next;
size--;
return delNode;
}
@Override
public void insert(int index, E data) {
Node newNode = new Node(data);
Node preNode = head;
if (index > getSize()) return;
for (int i = 1; i < index; i++) {
preNode = preNode.next;
}
Node successor = preNode.next;
preNode.next = newNode;
newNode.next = successor;
size++;
}
@Override
public int getSize() {
return size;
}
@Override
public Object getData(int index) {
Node temp = head;
if (index > getSize()) return null;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
return temp.data;
}
@Override
public void print() {
Node temp = head.next;
while (temp != null) {
System.out.print(temp.data + " ");
temp = temp.next;
}
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public void clear() {
head.next = null;
size = 0;
}
}
class Client
package com.skystep.数据结构和算法.链表.单向链表;
public class Client {
public static void main(String[] args) {
LinkedList<Integer> singleLinkedList = new SingleLinkedList<>();
singleLinkedList.add(1);
singleLinkedList.add(2);
singleLinkedList.add(3);
singleLinkedList.insert(3, 10);
System.out.println("size:" + singleLinkedList.getSize());
singleLinkedList.print();
System.out.println();
System.out.println("第3个的值是:" + singleLinkedList.getData(3));
singleLinkedList.delete(4);
System.out.println("size:" + singleLinkedList.getSize());
singleLinkedList.print();
System.out.println();
System.out.println("第2个的值是:" + singleLinkedList.getData(2));
singleLinkedList.clear();
System.out.println("size:" + singleLinkedList.getSize());
singleLinkedList.print();
}
}