线性表-链表
1. 原理
把结点看成对象,对象中有两个属性:
- 这个结点中装的元素;
- 下个结点的位置(指向下个结点对象的引用)。
class Node {
int val; // 保存元素
Node next; // 保存指向下一个结点的引用;其中尾结点的 next == null
}
我们通过链表的头结点,来代表一整条链表。
2. 链表的常见操作
2.1 链表的结点定义
public class Node {
public String val;
public Node prev;
public Node next;
public Node(String val){
this.val = val;
}
@Override
public String toString() {
return "Node{" + "val=" + val + "}";
}
}
2.2 链表的手工创建
Node n1 = new Node("1");
Node n3 = new Node("2");
Node n2 = new Node("4");
Node n6 = new Node("6");
n1.next = n3;
n3.next = n2;
n2.next = n6;
n6.next = null;
Node head = n1;
创建一个空链表
Node head = null;
2.3 链表的遍历
Node cur = head;
while (cur != null) {
System.out.println(cur.val);
cur = cur.next;
}
2.4 链表的元素插入和删除
给定前驱结点后的插入
Node prev = ...; // 给定结点的前驱结点
Node node = new Node("v");
node.next = prev.next;
prev.next = node;
给定前驱节点后的删除
Node prev = ...; // 待删除的结点的前驱节点
prev.next = prev.next.next;
头插
private static Node pushFront(Node head, String v){
Node node = new Node(v);
node.next = head;
head = node;
return head;
}
头删
private static Node popFront(Node head){
if (head == null){
throw new RuntimeException("链表为空");
}
head = head.next;
return head;
}
尾插
private static Node pushBack(Node head, String v){
if (head == null){
Node node = new Node(v);
return node;
}
Node last = head;
while (last.next != null){
last = last.next;
}
Node node = new Node(v);
last.next = node;
return head;
}
尾删
private static Node popBack(Node head){
if (head == null){
throw new RuntimeException("链表为空");
}
if (head.next == null){
return null;
}
Node last2 = head;
while (last2.next.next != null){
last2 = last2.next;
}
last2.next = null;
return head;
}
3. Java中的链表 - LinkedList
- LinkedList 实现了 List 接口,LinkedList 具备的方法,等同于 LIst 具备的方法;
- Java 中的链表,不再使用头结点来代替边表,而是定义了一个链表类来表示链表;
- Java 中的链表采用的是一种双向链表;
- Java 中的链表既保存了链表的头结点,也保存了尾结点。
4. 实现自己的LinkedList - MyLinkedList
public class Node {
public String val;
public Node prev;
public Node next;
public Node(String val){
this.val = val;
}
@Override
public String toString() {
return "Node{" + "val=" + val + "}";
}
}
public class MyLinkedList {
private Node head;
private Node last;
private int size;
public MyLinkedList(){
head = null;
last = null;
size = 0;
}
public boolean add(String e){
Node node = new Node(e);
if (head == null){
head = last= node;
}else {
node.prev = last;
last.next = node;
last = node;
}
size++;
return true;
}
public void add(int index, String e){
if (index < 0 || index > size){
throw new ArrayIndexOutOfBoundsException();
}
if (head == null){
Node node = new Node(e);
head = last = node;
}else if (index == 0){
Node node = new Node(e);
node.next = head;
head.prev = node;
head = node;
}else if (index == size){
Node node = new Node(e);
last.next = node;
node.prev = last;
last = node;
}else {
Node node = new Node(e);
Node pre = head;
for (int i = 0; i < index - 1; i++){
pre = pre.next;
}
Node next = pre.next;
pre.next = node;
next.prev = pre;
node.next = next;
next.prev = node;
}
size++;
}
public String remove(int index){
if (index < 0 || index >= size){
throw new ArrayIndexOutOfBoundsException();
}
String e;
if (size == 1){
e = head.val;
head = last = null;
}else if (index == 0){
e = head.val;
head = head.next;
head.prev = null;
}else if (index == size - 1){
e = last.val;
last = last.prev;
last.next = null;
}else {
Node toDelete = head;
for (int i = 0; i < index; i++){
toDelete = toDelete.next;
}
e = toDelete.val;
Node pre = toDelete.prev;
Node next = toDelete.next;
pre.next = next;
next.prev = pre;
}
size--;
return e;
}
boolean remove(String e){
int i = indexOf(e);
if (i < 0){
return false;
}
remove(i);
return true;
}
public String get(int index){
if (index < 0 || index >= size){
throw new ArrayIndexOutOfBoundsException();
}
Node findNode = head;
for (int i = 0; i < index; i++){
findNode = findNode.next;
}
return findNode.val;
}
public String set(int index, String e){
if (index < 0 || index >= size){
throw new ArrayIndexOutOfBoundsException();
}
Node setNode = head;
for (int i = 0; i < index; i++){
setNode = setNode.next;
}
setNode.val = e;
return e;
}
public boolean contains(String e){
return indexOf(e) > 0;
}
public int indexOf(String e){
int i = 0;
for (Node cur = head; cur != null; cur = cur.next){
if (cur.val.equals(e)){
return i;
}
i++;
}
return -1;
}
public int lastIndexOf(String e){
int i = size - 1;
for (Node cur = last; cur != null; cur = cur.prev){
if (cur.val.equals(e)){
return i;
}
i--;
}
return -1;
}
public void clear(){
head = last = null;
size = 0;
}
public int size(){
return size;
}
public boolean isEmpty() {
return size == 0;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder("[");
Node cur = head;
while (cur != null){
stringBuilder.append(cur.val);
if (cur.next != null){
stringBuilder.append(",");
}
cur = cur.next;
}
stringBuilder.append("]");
return stringBuilder.toString();
}
}