美文网首页Android专题模型与算法
从屌丝到架构师的飞越(数据结构篇)-链表

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

作者: 走着别浪 | 来源:发表于2019-07-01 07:26 被阅读75次

    一.介绍

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

    相关文章

      网友评论

        本文标题:从屌丝到架构师的飞越(数据结构篇)-链表

        本文链接:https://www.haomeiwen.com/subject/sxsucctx.html