链表

链表的类型

单链表,双端链表,有序链表,双向链表,有迭代器的链表(迭代器是用来随机访问链表元素的一种方法)。

 

单链表

链表本身是由一个个的link对象构成的。每个link对象都包含两个部分:

1,数据本身。

2,指向下一个link对象的引用。

因此链表就是很多的link对象,它们根据引用互相连接,形成了一个逻辑上的链表。而实际这些link对象在物理上并不一定是相邻的。

由此可见,每个link对象仅知道下一个link对象的位置,而无法知道其他对象的位置,比如,上一个link对象,或下个link对象后面的那个link对象。

这就意味着,如果想取出第12个数据项,必须遍历前11个数据项。


下面是java实现:

Link类是链表上的节点,LinkList是链表本身。

public class LinkList {
    private Link first;
    public LinkList(){
        first = null;  //first代表链表的第一个节点。一开始,链表为null,因此第一个节点也为空。
    }
    
    public void insertFirst(int id){
        Link newLink = new Link(id); //这里的思想就是永远在链表头插入节点。
        newLink.next = first; //首先把新插入的节点的next指向first,也就是之前的那个节点。第一次循环的时候,first为null。
        first = newLink; //然后新插入的节点成了链表的第一个节点。由于总是在表头插入新节点,再加上链表只能单向查询,因此查出来的元素顺序总是倒叙的。

//在链表尾部插入数据可以实现,但效率低下。因为总是得顺着链表移动到尾部后,才能插入数据。
    }
    
    public void displayList(){
        Link current = first;
        while(current != null){  //循环的打印出每个节点。
            current.displayLink();
            current = current.next;
        }
    }

  public void delete(String key){
        Link current = first;
        Link previous = first; //因为需要将前一个Link.next指向被删除link后面的那个link,所以需要保存previous以便于修改。
        while(current.sData != key){
            {
                if(current.next == null){
                }else{
                    previous = current;
                    current = current.next;
                }
            }
        }
        if(current == first){
            first = first.next;
        }else{
            previous.next = current.next;
        }           
    }

}


class Link {
    public int iDate;
    public Link next; 
    public Link(int id){
        iDate = id;
    }
    
    public void displayLink(){
        System.out.println("{" + iDate + "}");
    }
}


双端链表

 

注意是双端链表而不是双向链表。双端链表和单链表唯一的区别就是,在first不仅指向链表的开头,同时也指向链表的结尾(即在LinkList类,不仅有first,而且有last)。这样,就可以方便的在链表尾部插入数据了。

这使得双端链表可以用于实现队列。因为队列总是在链表尾部插入新节点的。

但是在双端链表中,仍然不能高效的删除最后一个节点。只有双向链表才能解决这个问题。

双端链表的实现:

public class LinkList {
    private Link first;
    private Link last;
    
    public LinkList(){
        first = null;
        last = null;
    }
    
    public void insertFirst(String s){
        Link newLink = new Link(s);
        if(isEmpty()){
            first = newLink;
            last = newLink;
        }else{            
            newLink.next = first;
            first = newLink;
        }
        
    }
    
    public void insertLast(String s){
        Link newLink = new Link(s);
        if(isEmpty()){
            first = newLink;
            last = newLink;
        }else{
            last.next = newLink;
            last = newLink;
        }
    }
    
    public void displayLink(){
        Link current = first;
        while(current != null){
            current.displayLink();
            current = current.next;
        }
    }
    
    public boolean isEmpty(){
        if(first == null || last == null){
            return true;
        }
        else{
            return false;
        }
    }
}


双向链表

使用双向链表可以很容易的正向查询数据和反向查询数据。实现方法是每个link节点不仅有指向下一个节点的reference,也有指向上个节点的reference。

缺点就是每插入一个节点,就需要修改4个reference(不过也还能接受吧)。

链表的效率

在表头插入和删除都是O(1)。查找,删除和在制定节点插入都是O(n)。所以和数组操作一样。但是链表插入和删除都不需要移动其他节点,所以这方面比数组效率高。


有序链表

有序链表查找和删除的效率是O(n),因为在有序链表里搜索,仍然需要遍历链表。但是如果需要频繁的插入删除最小值,则有序列表非常适合。比如用来实现优先级队列。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值