一.介绍
链表是一种数据结构,和数组同级。比如,Java中我们使用的ArrayList,其实现原理是数组。而LinkedList的实现原理就是链表了。链表在进行循环遍历时效率不高,但是插入和删除时优势明显。
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。
二.知识点介绍
1、单向链表原理
2、LinkdList常用方法
3、双端链表
4、有序链表
三.上课对应视频的说明文档
1、单向链表原理
单向链表是一种线性表,实际上是由节点(Node)组成的,一个链表拥有不定数量的节点。其数据在内存中存储是不连续的,它存储的数据分散在内存中,每个结点只能也只有它能知道下一个结点的存储位置。由N各节点(Node)组成单向链表,每一个Node记录本Node的数据及下一个Node。向外暴露的只有一个头节点(Head),我们对链表的所有操作,都是直接或者间接地通过其头节点来进行的。
上图中最左边的节点即为头结点(Head),但是添加节点的顺序是从右向左的,添加的新节点会被作为新节点。最先添加的节点对下一节点的引用可以为空。引用是引用下一个节点而非下一个节点的对象。因为有着不断的引用,所以头节点就可以操作所有节点了。
下图描述了单向链表存储情况。存储是分散的,每一个节点只要记录下一节点,就把所有数据串了起来,形成了一个单向链表。
节点(Node)是由一个需要储存的对象及对下一个节点的引用组成的。也就是说,节点拥有两个成员:储存的对象、对下一个节点的引用。下面图是具体的说明:
2、LinkedList常用方法
(1) 链表LinkedList是由若干个称为结点的对象组成的一种数据结构,每个结点含有一个数据和下一个结点的引用,或含有一个数据并含有上一个结点的引用和下一个结点的引用。
(2) 常用方法
public boolean add(Object o):向链表添加一个新的结点o(只能向链表中添加对象,不能添加某个基本数据类型的数)
public void add(int index,Object o):向链表的指定位置index处添加一个新的结点o
public void addFirst(Object o):向链表的头添加新的结点o
public void addLast(Object o):向链表的末尾添加新的结点o
public void clear():删除链表的所有结点,使当前链表成为空链表
public Object remove(int index):删除指定位置index上的结点
public boolean remove(Object o):删除首次出现含有数据o的结点
public Object removeFirst():删除第一个结点,并返回这个结点中的对象
public Object removeLast():删除最后一个结点,并返回这个结点中的对象
public Object get(int index):获取链表中指定位置index处结点中的对象
public Object getFirst():获取链表中第一个结点中的对象
public Object getLast():获取链表中最后一个结点中的对象
public int indexOf(Object o):返回含有数据o的结点在链表中首次出现的位置,如果链表中无此结点,则返回-1
public int lastIndexOf(Object o):返回含有数据o的结点在链表中最后出现的位置,如果链表中无此结点,则返回-1
public Object set(int index,Object o):将当前链表index位置结点中的对象替换为参数o指定的对象,并返回被替换的对象
public int size():返回链表的长度,即结点的个数
public boolean contains(Object o):判断链表结点中是否有结点含有对象o
案例1:
import java.util.*;
public class LLTest{
public static void main(String args[]){
LinkedList l=new LinkedList();
for(int i=0;i<=5;i++){
l.add("a"+i);
}
l.add(3,"a100"); //添加
System.out.println(l);
l.set(6,"a200"); //更改
System.out.println(l);
System.out.println(l.get(2)); //获取值
System.out.println(l.indexOf("a3")); //下标
l.remove(1); //移除
System.out.println(l);
System.out.println(l.indexOf("a3"));
}
}
案例2:
import java.util.*;
public class LLTest2{
public static void main(String args[]){
LinkedList l=new LinkedList();
l.add("a1");
l.add("a2");
System.out.println(l);
l.addFirst("a100"); //添加到头
l.addLast("a200"); //添加到尾
System.out.println(l);
System.out.println(l.getFirst()); //获取头
System.out.println(l.getLast()); //获取尾
l.removeFirst(); //移除头
l.removeLast(); //移除尾
System.out.println(l);
}
}
案例:单项链表
public class LinkedList {
//声明一个内部类
private class Data{
private Object obj;
private Data next = null;
Data(Object obj){
this.obj = obj;
}
}
private Data first = null;
//加入元素对象
public void insertFirst(Object obj){
Data data = new Data(obj);
data.next = first;
first = data;
}
//删除元素对象
public Object deleteFirst() throws Exception{
if(first == null)
throw new Exception("empty!");
Data temp = first;
first = first.next;
return temp.obj;
}
//查看对象元素
public Object find(Object obj) throws Exception{
if(first == null)
throw new Exception("LinkedList is empty!");
Data cur = first;
while(cur != null){
if(cur.obj.equals(obj)){
return cur.obj;
}
cur = cur.next;
}
return null;
}
//移出对象
public void remove(Object obj) throws Exception{
if(first == null)
throw new Exception("LinkedList is empty!");
if(first.obj.equals(obj)){
first = first.next;
}else{
Data pre = first;
Data cur = first.next;
while(cur != null){
if(cur.obj.equals(obj)){
pre.next = cur.next;
}
pre = cur;
cur = cur.next;
}
}
}
//判断是否有对象
public boolean isEmpty(){
return (first == null);
}
//显示对象
public void display(){
if(first == null)
System.out.println("empty");
Data cur = first;
while(cur != null){
System.out.print(cur.obj.toString() + " -> ");
cur = cur.next;
}
System.out.print("\n");
}
public static void main(String[] args) throws Exception {
LinkedList ll = new LinkedList();
ll.insertFirst(4);
ll.insertFirst(3);
ll.insertFirst(2);
ll.insertFirst(1);
ll.display();
ll.deleteFirst();
ll.display();
ll.remove(3);
ll.display();
System.out.println(ll.find(1));
System.out.println(ll.find(4));
}
}
3、双端链表
双端链表(不是双向链表):与单向链表的不同之处在保存有对最后一个链接点的引用(last)
案例:
public class FirstLastList {
private class Data{
private Object obj;
private Data next = null;
Data(Object obj){
this.obj = obj;
}
}
private Data first = null;
private Data last = null;
//插入对象
public void insertFirst(Object obj){
Data data = new Data(obj);
if(first == null)
last = data;
data.next = first;
first = data;
}
//尾部插入对象
public void insertLast(Object obj){
Data data = new Data(obj);
if(first == null){
first = data;
}else{
last.next = data;
}
last = data;
}
//删除头部第一个对象
public Object deleteFirst() throws Exception{
if(first == null)
throw new Exception("empty");
Data temp = first;
if(first.next == null)
last = null;
first = first.next;
return temp.obj;
}
//删除最后一个对象
public void deleteLast() throws Exception{
if(first == null)
throw new Exception("empty");
if(first.next == null){
first = null;
last = null;
}else{
Data temp = first;
while(temp.next != null){
if(temp.next == last){
last = temp;
last.next = null;
break;
}
temp = temp.next;
}
}
}
//显示对象
public void display(){
if(first == null)
System.out.println("empty");
Data cur = first;
while(cur != null){
System.out.print(cur.obj.toString() + " -> ");
cur = cur.next;
}
System.out.print("\n");
}
public static void main(String[] args) throws Exception {
FirstLastList fll = new FirstLastList();
fll.insertFirst(2);
fll.insertFirst(1);
fll.display();
fll.insertLast(3);
fll.display();
fll.deleteFirst();
fll.display();
fll.deleteLast();
fll.display();
}
}
4、有序链表
有序链表:链表中的数据按从小到大排列
案例:
public class SortedList {
private class Data{
private Object obj;
private Data next = null;
Data(Object obj){
this.obj = obj;
}
}
private Data first = null;
//插入对象
public void insert(Object obj){
Data data = new Data(obj);
Data pre = null;
Data cur = first;
while(cur != null && (Integer.valueOf(data.obj.toString())
.intValue() > Integer.valueOf(cur.obj.toString())
.intValue())){
pre = cur;
cur = cur.next;
}
if(pre == null)
first = data;
else
pre.next = data;
data.next = cur;
}
//删除对象
public Object deleteFirst() throws Exception{
if(first == null)
throw new Exception("empty!");
Data temp = first;
first = first.next;
return temp.obj;
}
//显示对象
public void display(){
if(first == null)
System.out.println("empty");
System.out.print("first -> last : ");
Data cur = first;
while(cur != null){
System.out.print(cur.obj.toString() + " -> ");
cur = cur.next;
}
System.out.print("\n");
}
public static void main(String[] args) throws Exception{
SortedList sl = new SortedList();
sl.insert(80);
sl.insert(2);
sl.insert(100);
sl.display();
System.out.println(sl.deleteFirst());
sl.insert(33);
sl.display();
sl.insert(99);
sl.display();
}
}