本次学习内容是链表,包括单链表、双端链表、有序链表、双向链表,最后的学习内容为迭代器
对于空间连续的数组,无序的查询慢,有序就插入慢,针对以上两种情况,链表在一定程度上缓解了这个问题。
1-单链表。
单链表首先要定义一个节点,然后再定义节点之间的关系。节点除了保存数据之外,还保存着相邻下一个节点的引用,可以通过引用找到下一个节点。
单链表的简单代码实现:
/*
* 定义一个单链表,链表只能进行以下操作
* 1:在表头插入元素
* 2:在表头删除元素
* 3:遍历数据
* 4:查找元素
* */
public class LinkedList<E> {
private Node root;
// 表头插入数据
public void push(E d) {
Node tmp = new Node(d);
if (root == null) {
root = tmp;
} else {
tmp.next = root;
root = tmp;
}
}
// 删除表头
public E pop() {
E ret = null;
if (root != null) {
ret = (E) root.data;
root = root.next;
}
return ret;
}
// 遍历
public void display() {
if (null == root) {
return;
}
Node tmp = root;
while (tmp != null) {
System.out.println("data is " + tmp.data);
tmp = tmp.next;
}
}
// 查找数据
public void find(E key) {
if (root == null) {
return;
}
Node<E> tmp = root;
while (tmp != null && !key.equals(tmp.data)) {
tmp = tmp.next;
}
if (tmp != null) {
System.out.println("find the key value");
} else {
System.out.println("not find the key value");
}
}
private class Node<E> {
public E data;
public Node<E> next;
public Node(E data) {
this.data = data;
next = null;
}
}
}
2-双端链表
双端链表有点类似于队列,记录了头和尾,可以在两端操作。但是数组的实现方式为了不浪费空间,使用循环队列的方式。但是链表就不用这么麻烦。删除的空间因为没有不在引用,自动回收。
双端队列的结构:
public class LinkedList<E> {
private Node first;
private Node last;
}
然后在链表的头和尾都能插入和删除元素,相当于栈和队列的合体。
具体代码比较简单,就不写了。
链表的特点就是插入删除快(常数时间),查询慢(O(N))。
3-双向队列
双向队列的特点是一个节点不但保存这后继节点的引用,还保存这前驱节点的引用。
这样队列的操作都可以是双向的。比如查找链表后半部分的数据就不用只能从表头开始,减少了查询的次数。
代码实现如下:
public class DDLinkedList<E> {
private Node<E> head;
private Node<E> tail;
public DDLinkedList() {
head = null;
tail = null;
}
public void InserttoHead(E data) {
Node<E> tmp = new Node<E>(data);
if (head == null) {
head = tmp;
tail = tmp;
} else {
tmp.next = head;
head.pre = tmp;
head = tmp;
}
}
public void inserttoTail(E data) {
Node<E> tmp = new Node<E>(data);
if (tail == null) {
head = tmp;
tail = tmp;
} else {
tail.next = tmp;
tmp.pre = tail;
tail = tmp;
}
}
public E deletefromHead() {
if (head == null) {
return null;
}
E tmp = head.data;
if (head.next != null) {
head.next.pre = null;
}
head = head.next;
return tmp;
}
public E deletefromTail() {
if (tail == null) {
return null;
}
E tmp = tail.data;
if (tail.pre != null) {
tail.pre.next = null;
tail = tail.pre;
}
return tmp;
}
// 参数 dir-方向,0为正向,1为反向
public void display(int dir) {
if (0 == dir) {
Node<E> tmp = head;
System.out.print("链表正向数据:{");
while (tmp != null) {
System.out.print("" + tmp.data);
if (!tmp.equals(tail)) {
System.out.print(",");
}
tmp = tmp.next;
}
System.out.print("链表数据:{");
} else {
Node<E> tmp = tail;
System.out.print("链表反向数据:{");
while (tmp != null) {
System.out.print("" + tmp.data);
if (!tmp.equals(tail)) {
System.out.print(",");
}
tmp = tmp.pre;
}
System.out.print("链表数据:{");
}
}
private class Node<E> {
E data;
Node<E> pre;
Node<E> next;
public Node(E d) {
data = d;
pre = null;
next = null;
}
}
}
本节简单的学习了一下链表。
链表通过设计节点和节点的保存内容,以及节点关系的保存不同而不同。简单的就是以上所说的单链表、双端链表和双向链表。
我觉得链表的特点就是离散的线性逻辑结构。
最后还设计了一点迭代器的内容,需要进一步理解后再总结。