线性数据结构
# 链表为什么重要
- 链表 真正的数据结构
- 最简单的动态数据结构
- 更深入的理解引用(或者指针)
- 更深入的理解递归
- 辅助组成其他数据结构
链表Linked List
- 数据存储在“节点”(node)中
- 优点:真正的动态,不需要处理固定容量的问题
缺点:丧失了随机访问的能力
数组与链表的对比
- 数组最好用于索引有语义的情况。index[2]
- 最大的优点:支持快速查询
- 链表不适合于有索引有语义的情况
- 最大的优点:动态
coding
在这里插入代码片
链表的时间复杂度
- 添加操作
addLast(e) O(n)
addFirst(e) O(1)
add(index,e) o(n/2) = o(n) - 删除操作
removeLast(e) O(n)
removeLast(e) O(1)
remove(index,e) O(n) - 修改操作
set(index,e) O(n)
contains(e) O(n)
find(e) O(n)
综上所述
链表的 增删改查时间复杂度都是O(n)
增删查的只对链表进行操作时间复杂度都是O(1)
coding
package arithmetic.LinkedList;
public class LinkedList<E> {
private class Node {
public E e;
public Node next;
public Node(E e, Node next) {
this.e = e;
this.next = next;
}
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(null, null);
size = 0;
}
//获取链表中的元素个数
public int getSize() {
return size;
}
//返链表是否为空
public boolean isEmpty() {
return size == 0;
}
//在链表的中间添加元素
public void add(E e) {
Node node = new Node(e);
}
public void add(int index, E e) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed .Illegal index");
}
Node prev = dummyHead;
for (int i = 0; i < index; i++) {
prev = prev.next;
}
// Node node = new Node(e);
// node.next = prev.next;
// prev.next = node;
//上面3句=下面一句
prev.next = new Node(e, prev.next);
size++;
}
//在链表中添加新的元素e
public void addFirst(E e) {
add(0, e);
size++;
}
public void addLast(E e) {
add(size, e);
}
//在链表的index(0-based)位置添加新的元素e
//在链表中不是一个常用的操作。练习用:)
public E get(int index) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed .Illegal index");
}
Node cur = dummyHead.next;
for (int i = 0; i < index; i++) {
cur = cur.next;
}
return cur.e;
}
//获得链表的第一个元素
public E getFirst() {
return get(0);
}
//获得聊表的最后一个元素
public E getLast() {
return get(size - 1);
}
//修改链表的第index(0-based)个位置的元素为e
//在链表中不是一个常用的操作
public void set(int index, E e) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed .Illegal index");
}
Node node = dummyHead.next;
for (int i = 0; i < index; i++) {
node = node.next;
}
node.e = e;
}
//查找链表中是否有元素e
public boolean contains(E e) {
Node node = dummyHead.next;
// for(int i=0;i<size;i++){
// if (node != null){
// if (node.equals(e)){
// return true;
// }else {
// node = node.next;
// }
// }
// }
while (node != null) {
if (node.equals(e)) {
return true;
} else {
return false;
}
}
return false;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
Node cur = dummyHead.next;
while (cur != null) {
stringBuilder.append(cur + "->");
cur = cur.next;
}
stringBuilder.append("NULL");
return stringBuilder.toString();
}
//从链表中删除index(0-based)位置的元素,返回被删除的元素
public E remove(int index) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed .Illegal index");
}
Node prev = dummyHead;
Node cur = prev.next;
Node del = null;
for (int i = 0; i <= index; i++) {
if (i == index) {
del = cur;
prev.next = cur.next;
cur.next = null;
cur = null;
}
if (cur != null){
prev = cur;
cur = cur.next;
}
}
size -- ;
return del.e;
}
//从链表中删除第一个元素,返回删除的元素
public E removeFirst() {
return remove(0);
}
//从链表中删除最后一个元素,返回删除的元素
public E removeEnd() {
return remove(size - 1);
}
}
package arithmetic.LinkedList;
public class LinkedListStack<E> implements Stack<E> {
private LinkedList<E> linkedList;
public LinkedListStack() {
this.linkedList = new LinkedList<>();
}
@Override
public int getSize() {
return linkedList.size;
}
@Override
public boolean isEmpty() {
return linkedList.isEmpty();
}
@Override
public void push(E e) {
linkedList.addFirst(e);
}
@Override
public E pop() {
return linkedList.removeFirst();
}
@Override
public E peek() {
return linkedList.getFirst();
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Stack : top ");
stringBuilder.append(linkedList);
return stringBuilder.toString();
}
public static void main(String[] args) {
LinkedListStack<Integer> stack = new LinkedListStack<>();
for (int i=0;i<5;i++){
stack.push(i);
System.out.println(stack);
}
System.out.println("-----------");
stack.peek();
System.out.println(stack);
}
}
package arithmetic.LinkedList;
public class LinkedQueue<E> implements Queue<E> {
private class Node {
public E e;
public Node next;
public Node(E e, Node next) {
this.e = e;
this.next = next;
}
public Node(E e) {
this(e, null);
}
public Node() {
this(null, null);
}
@Override
public String toString() {
return e.toString();
}
}
private Node head, tail;
private int size;
public LinkedQueue() {
this.head = null;
this.tail = null;
this.size = 0;
}
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public void enqueue(E e) {
if (tail == null) {
tail = new Node(e);
head = tail;
} else {
tail.next = new Node(e);
tail = tail.next;
}
size++;
}
@Override
public E dequeue() {
if (tail == null)
throw new IllegalArgumentException("Cannot dequeue from queue .");
Node returnNode = head;
System.out.println("head: " + head);
System.out.println("head.next: " +head.next);
System.out.println("head.returnNode: " +head.next);
System.out.println("---------------------------");
head = head.next;
returnNode.next = null;
if (head == null) {
tail = null;
}
size--;
return returnNode.e;
}
@Override
public E getFront() {
if (isEmpty()) {
throw new IllegalArgumentException("Queue is null");
}
return head.e;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Queue: front ");
Node cur = head;
while (cur != null) {
stringBuilder.append(cur + "->");
cur = cur.next;
}
stringBuilder.append("NULL tail ");
return stringBuilder.toString();
}
public static void main(String[] args) {
LinkedQueue<Integer> queue = new LinkedQueue<>();
for (int i = 0; i < 10; i++) {
queue.enqueue(i);
System.out.println(queue);
if (i % 3 == 2) {
queue.dequeue();
System.out.println(queue);
}
}
}
}
package arithmetic.LinkedList;
public class Main {
public static void main(String[] args) {
LinkedList<Integer> linkedList = new LinkedList<>();
for (int i = 0; i < 5; i++) {
linkedList.addFirst(i);
System.out.println(linkedList);
}
System.out.println("--------");
linkedList.add(2,666);
System.out.println(linkedList);
linkedList.remove(1);
System.out.println("--------");
System.out.println(linkedList);
// linkedList.removeEnd();
// System.out.println("--------");
// System.out.println(linkedList);
}
}