链表的实现(Linked List)
Posted You295
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链表的实现(Linked List)相关的知识,希望对你有一定的参考价值。
链表的实现(Linked List)
链表的概念
是一种在物理上非连续、非顺序的数据结构,由若干个节点(node)所组成。
优缺点
优点:真正的动态,不需要处理固定容量的问题
缺点:丧失了随机访问的能力
链表与数组的对比
数组最好用于索引有语意,优点为支持快速查询
链表不适用与索引有语意的情况,优点:动态
构成以及基本功能底层的实现
1)底层创建节点
public class Node {
public Object data;
public Node next;
public Node() {
}
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public String toString() {
return "Node [data=" + data + ", next=" + next + "]";
}
}
2)底层实现链表头插法:
public class MyLinkedList {
public Node head; // 头结点
public int size;
/**
* 头插法
*
* @param data
*/
public void addFirst(Object data) {
final Node newNode = new Node(data, null); // 定义节点
if (head == null) { // 空链表
head = newNode;
} else {
newNode.next = head;
head = null;
head = newNode;
}
size++;
}
测试:
public static void main(String[] args) {
MyLinkedList list = new MyLinkedList();
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);
System.out.println(list);
//输出>>MyLinkedList [head=Node [data=3, next=Node [data=2, next=Node [data=1, next=null]]], size=3]
3)尾插实现:
/**
* 尾插法
*/
public void addLast(Object data) {
final Node newNode = new Node(data, null); // 定义节点
if (head == null) { // 空链表
head = newNode;
} else {
Node p = head;
while (p.next != null) {
p = p.next; // 遍历扫描到尾端
}
p.next = newNode; // 尾端插入
}
size++;
}
测试:
public static void main(String[] args) {
MyLinkedList list = new MyLinkedList();
list.addLast(1);
list.addLast(2);
list.addLast(3);
System.out.println(list);
//输出>>>MyLinkedList [head=Node [data=1, next=Node [data=2, next=Node [data=3, next=null]]], size=3]
4)底层实现找到链表的中间节点(快慢引用法):
public void halfNodeTest() {
MyLinkedList list = new MyLinkedList();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
list.addLast(5);
list.addLast(6);
list.addLast(7);
System.out.println(halfNode(list.head).data);
}
private static Node halfNode(Node head) { // 找到链表的中间位置,利用双指针法
Node left = head; // 慢指针
Node right = head; // 快指针
while (right != null && left.next != null) {
right = right.next.next;
left = left.next;
}
return left;
}
}
5)指针法判断链表节点个数的奇偶性
/**
* 判断链表个数的奇偶性
*/
@Test
public void test() {
MyLinkedList list = new MyLinkedList();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
list.addLast(5);
list.addLast(6);
OddOrEven(list.head);
//输出>>>偶数个
}
private void OddOrEven(Node head) {
Node right = head;
try {
while (right.next != null) {
right = right.next.next; // 指针以两倍速度去跑
}
System.out.println("奇数个");
} catch (Exception e) {
System.out.println("偶数个");
}
}
6)根据指定位置去插入元素
/**
* 指定位置去插入元素
*/
public void addList(Object data, int index) {
if (index == 0) {
addFirst(data); // 当在0位置插入,直接调用前插
} else if (index == this.size) {
addLast(data); // 当在末尾位置插入,直接调用尾插
} else {
Node p = head;
Node newNode = new Node(data, null);
for (int i = 0; i < index - 1; i++) { // 找到指定位置的前一个位置
p = p.next;
}
newNode.next = p.next; // 连接操作
p.next = newNode;
}
size++;
}
测试;
@Test
public void test01() {
MyLinkedList list = new MyLinkedList();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
list.addLast(5);
list.addLast(6);
list.print();
System.out.println(">>>>>>>>>>>");
list.addList(99, 3);
list.print();
}
7)根据index找到元素位置
/**
* 根据index找到位置
*/
public Node findNode(int index) {
Node p = head;
for(int i=0;i<index;i++) { //利用循环遍历
p = p.next;
}
return p;
}
测试:
/**
* 测试根据index找到位置
*/
@Test
public void test02() {
MyLinkedList list = new MyLinkedList();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
list.addLast(5);
list.addLast(6);
System.out.println(list.findNode(3).data);
}
//输出>>>4
8)删除元素
/**
* 删除元素
*/
public void remove(int index) {
if(index==0) { //删除头结点
final Node p = head.next;
head.next = null;
head = p;
}else if(index==(this.size-1)) { //删除尾结点
Node p = findNode(size-2); //找到倒数第二个节点
p.next = null;
}else {
Node p = findNode(index-1);//找到删除位置的前一个位置
Node after = p.next.next;
p.next = after;
}
}
测试:
/**
* 测试删除元素
*/
@Test
public void test03() {
MyLinkedList list = new MyLinkedList();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
list.addLast(5);
list.addLast(6);
list.print();
System.out.println(">>>>>>>>>");
list.remove(2);
list.print();
}
以上是关于链表的实现(Linked List)的主要内容,如果未能解决你的问题,请参考以下文章
Python实现单向有序链表(Singly linked list)
876. (Middle of the Linked List)链表的中间结点
Leetcode 237. Delete Node in a Linked List-删除链表的指定节点,不给链表的头节点