从屌丝到架构师的飞越(数据结构篇)-链表

一.介绍

链表是一种数据结构,和数组同级。比如,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(); 

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容