目录
1.链表的重要性
2.链表的实现
对于链表来说我们想要访问存在在这个链表的所有节点,必须存放他的头
往链表中添加元素
在链表的中间添加新的元素,在索引为2的地方添加元素666
思路:你得先找到索引为2的前一个元素是什么,只能通过遍历,找到索引为1的元素,然后创建出新的元素,索引为1的next赋值给新元素的next,新元素赋值给索引为1的next
自己先写出来,
实现链表元素的添加和输出
package com.wx.test01.data;
/**
* Created by wangxiang on 2021/5/25
*/
public class LinkedList<E> {
/**
* 设计成私有的内部类
*/
private class Node {
public E e;
/**
* 设计成公有的属性,方便外部类操作,且不需要get set方法
*/
public Node next;
public Node(E e, Node node) {
this.e = e;
this.next = node;
}
public Node(E e) {
this(e, null);
}
public Node() {
this(null, null);
}
@Override
public String toString() {
return e.toString();
}
}
/**
* 整条链表的头
*/
private Node head;
/**
* 链表的容量
*/
int size;
/**
* 返回
*
* @return
*/
public int getLinkedSize() {
return this.size;
}
/**
* 往链表的首部添加元素
*
* @param e
*/
public void addFirstNode(E e) {
Node node = new Node(e, head);
head = node;
size++;
}
/**
* 往链表的中间添加元素
*
* @param index
* @param e
*/
public void add(int index, E e) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed!.Illegal index.");
}
if (index == 0) {
addFirstNode(e);
}
//找到前index元素,pre
// Node node = new Node(e);
Node pre = head;
for (int i = 0; i < index - 1; i++) {
pre = pre.next;
}
// 目前这个pre 就是index位置的前一个节点
// node.next = pre.next;
// pre.next = node;
pre.next = new Node(e, pre.next);
size++;
}
/**
* 在链表的末尾添加元素
*
* @param e
*/
public void addLast(E e) {
add(size, e);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Node pre = head;
for (int i = 0; i <= size - 1; i++) {
sb.append(pre.e).append("->");
pre = pre.next;
}
sb.append("NULL");
return sb.toString();
}
}
输出:
3.使用链表的虚拟头结点(链表技巧)
这样链表中所有的元素都不具有特殊性,因为他们都有前一个元素,这个虚拟的头节点是一个存null数据的节点,而他本身并不是null
添加虚拟头节点:
package com.wx.test01.data;
/**
* Created by wangxiang on 2021/5/25
*/
public class LinkedList<E> {
/**
* 设计成私有的内部类
*/
private class Node {
public E e;
/**
* 设计成公有的属性,方便外部类操作,且不需要get set方法
*/
public Node next;
public Node(E e, Node node) {
this.e = e;
this.next = node;
}
public Node(E e) {
this(e, null);
}
public Node() {
this(null, null);
}
@Override
public String toString() {
return e.toString();
}
}
/**
* 整条链表的虚拟头节点
*/
private Node dummyHead;
/**
* 链表的容量
*/
int size;
public LinkedList() {
dummyHead = new Node();
size = 0;
}
/**
* 返回
*
* @return
*/
public int getLinkedSize() {
return this.size;
}
/**
* 往链表的首部添加元素
*
* @param e
*/
public void addFirstNode(E e) {
add(0, e);
}
/**
* 往链表的中间添加元素
*
* @param index
* @param e
*/
public void add(int index, E e) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed!.Illegal index.");
}
Node pre = dummyHead;
for (int i = 0; i < index; i++) {
pre = pre.next;
}
// 目前这个pre 就是index位置的前一个节点
pre.next = new Node(e, pre.next);
size++;
}
/**
* 在链表的末尾添加元素
*
* @param e
*/
public void addLast(E e) {
add(size, e);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Node pre = dummyHead.next;
for (int i = 0; i <size; i++) {
sb.append(pre.e).append("->");
pre = pre.next;
}
sb.append("NULL");
return sb.toString();
}
}
输出:
4.链表的遍历查询和修改
跟新链表中的元素
链表的删除
package com.wx.test01.data;
/**
* Created by wangxiang on 2021/5/25
*/
public class LinkedList<E> {
/**
* 设计成私有的内部类
*/
private class Node {
public E e;
/**
* 设计成公有的属性,方便外部类操作,且不需要get set方法
*/
public Node next;
public Node(E e, Node node) {
this.e = e;
this.next = node;
}
public Node(E e) {
this(e, null);
}
public Node() {
this(null, null);
}
@Override
public String toString() {
return e.toString();
}
}
/**
* 整条链表的虚拟头节点
*/
private Node dummyHead;
/**
* 链表的容量
*/
int size;
public LinkedList() {
dummyHead = new Node();
size = 0;
}
/**
* 返回
*
* @return
*/
public int getLinkedSize() {
return this.size;
}
/**
* 往链表的首部添加元素
*
* @param e
*/
public void addFirstNode(E e) {
add(0, e);
}
/**
* 往链表的中间添加元素
*
* @param index
* @param e
*/
public void add(int index, E e) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed!.Illegal index.");
}
Node pre = dummyHead;
for (int i = 0; i < index; i++) {
pre = pre.next;
}
// 目前这个pre 就是index位置的前一个节点
pre.next = new Node(e, pre.next);
size++;
}
/**
* 在链表的末尾添加元素
*
* @param e
*/
public void addLast(E e) {
add(size, e);
}
/**
* 链表的遍历查询
*
* @param index
* @return
*/
public E get(int index) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed!.Illegal index.");
}
Node pre = dummyHead.next;
for (int i = 0; i < index; i++) {
pre = pre.next;
}
return pre.e;
}
/**
* 获得链表的第一个元素
*
* @return
*/
public E getFirst() {
return get(0);
}
/**
* 获得链表的最后一个元素
*
* @return
*/
public E getLast() {
return get(size - 1);
}
/**
* 修改链表中的元素
*
* @param index
* @param e
*/
public void set(int index, E e) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed!.Illegal index.");
}
Node pre = dummyHead.next;
for (int i = 0; i < index; i++) {
pre = pre.next;
}
pre.e = e;
}
/**
* 链表中是否包含一个元素
*
* @param e
* @return
*/
public boolean contains(E e) {
Node pre = dummyHead.next;
for (int i = 0; i < size; i++) {
if (pre.e.equals(e)) {
return true;
}
pre = pre.next;
}
return false;
}
/**
* 从链表中删除一个元素
*
* @param e
*/
public void remove(int index) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed!.Illegal index.");
}
//删除元素的时候这里需要注意一下。要找到的是这个元素的前一个元素
Node pre = dummyHead;
for (int i = 0; i < index; i++) {
pre = pre.next;
}
Node removeE = pre.next;
pre.next = removeE.next;
removeE.next = null;
size--;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Node pre = dummyHead.next;
for (int i = 0; i < size; i++) {
sb.append(pre.e).append("->");
pre = pre.next;
}
sb.append("NULL");
return sb.toString();
}
}
时间复杂度分析