02_链表是如何实现的?
链表在内存是怎么样在内存中分配空间的?
链表有哪些特性?
链表的样子
链表的地址不是连续的,内部维护着下一个节点的地址。
节点的定义
public class LinkedNode<T> {
public T data; // 数据部分 可以是对象也可以是基本类型
public LinkedNode<T> next; // 指向下个节点
public LinkedNode(T data) {
this.data = data;
}
public void displayLink(){
System.out.println(data + ",");
}
}
单链表
Java代码实现
/**
* 单链表
*
* @author chenchao
*/
public class SingleLinkedList {
private LinkedNode<Integer> first;
public SingleLinkedList() {
this.first = null;
}
public boolean isEmpty() {
return (first == null);
}
// insertFirst
public void insertFirst(int value){
LinkedNode<Integer> newNode = new LinkedNode<>(value);
newNode.next = first; // newNode.next -> old first
first = newNode; // first -> newNode
}
// deleteFirst
public LinkedNode deleteFirst(){
LinkedNode temp = first; // temp -> first
first = first.next; // first.next -> first
return temp;
}
}
双端链表
Java代码实现
/**
* 双端链表
* @author chenchao
*/
public class FirstLastList {
private LinkedNode<Integer> first; // 头结点
private LinkedNode<Integer> last; // 尾节点
public FirstLastList() {
this(null,null);
}
public FirstLastList(LinkedNode<Integer> first, LinkedNode<Integer> last) {
this.first = first;
this.last = last;
}
// isEmpty
public boolean isEmpty(){
return first == null;
}
// insertFirst 头插入
public void insertFirst(int value){
LinkedNode newNode = new LinkedNode(value);
if (isEmpty()){
last = newNode;
}
newNode.next = first;
first = newNode;
}
// insertLast //尾插入
public void insertLast(int value){
LinkedNode newNode = new LinkedNode(value);
if (isEmpty()){
first = newNode;
}else {
last.next = newNode;
}
last = newNode;
}
// deleteFirst
public int deleteFirst(int value){
int temp = first.data;
if (first.next == null){
last = null;
}
first = first.next;
return temp;
}
// deleteLast 思考下从last端开始删除有问题吗
}
有序链表
如何对链表进行排序
双向链表
区别于双端链表,在LinkedNode节点中有前驱和后驱
之前的LinkedNode可能已经不在支持我们的功能,所以下面重新定义一个Node结构
如何插入和删除节点将变得更加复杂
/**
* 双向列表的实现
* @author chenchao
*/
public class DoubleLinkedList<T> {
private DoubleLinkedNode<T> first;
private DoubleLinkedNode<T> last;
public DoubleLinkedList() {
first = null;
last = null;
}
public boolean isEmpty(){ return first == null;}
// insertFirst
public void insertFirst(T value){
DoubleLinkedNode<T> newNode = new DoubleLinkedNode<T>(value);
if (isEmpty()){
last = newNode; // if empty last --> newNode
}else {
first.pre = newNode; // if not empty old first --> newNode
}
newNode.next = first; // newLink <-- old first
first = newNode; // first --> newNode
}
// insertLast
public void insertLast(T value){
DoubleLinkedNode<T> newNode = new DoubleLinkedNode<>(value);
if (isEmpty()){
first = newNode;
}else {
last.next = newNode;
newNode.pre = last;
}
}
public DoubleLinkedNode deleteFirst(){
DoubleLinkedNode temp = first;
if (first.next == null){
last = null;
}else {
first.next.pre = null; //first of previous will is null
}
first = first.next;
return temp;
}
public DoubleLinkedNode deleteLast(){
DoubleLinkedNode temp = last;
if (first.next == null){
first = null;
}else{
last.pre.next = null;
}
last = last.pre;
return temp;
}
}