经典数据结构系列之:链表的应用

时间:2020-04-13
本文章向大家介绍经典数据结构系列之:链表的应用,主要包括经典数据结构系列之:链表的应用使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1、前言

数据结构,是计算机编程中对数据存储最基本的操作,不同的数据结构适用不同的业务场景。如今大部分情况都是调用开发API封装好的类库,直接调用,几乎不需要程序员再去深究其中背后实现的逻辑,大大简化和减低了对程序员的要求。正是这种,知其然而不知其所以然,导致很多程序员缺乏对于底层结构的了解,分不清楚不同数据结构之间的性能差异,导致出现很多系统性能问题。

2、原理推导

链表的运用,链表是一种特殊的线性表,由一系列的节点组成,节点在链表中的顺序由节点元素中包含的对象链接顺序确定位置。链表中的节点一部分是自身的数据,另一部分为节点指向的下一个节点的引用。

示例中,第一个节点【9】包含指向下一个节点【5】的指针,自身的数据+指针,这样构成了一个单向链表中的节点。单向链表在表头插入和删除操作效率很高,对于链表来说就是修改指针的引用,时间复杂度为常量O(1)。查找功能时间复杂度为O(N),比数组要快,链表操作不需要移动和复制数据。

3、代码示例

# 链表数据封装

/**
 * 链表的数据封装
 */
public class LinkNodeFlat {

    private int id;
    private LinkNodeFlat nodeFlat;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public LinkNodeFlat getNodeFlat() {
        return nodeFlat;
    }

    public void setNodeFlat(LinkNodeFlat nodeFlat) {
        this.nodeFlat = nodeFlat;
    }

    public LinkNodeFlat(int id) {
        super();
        this.id = id;
    }

    public void printLink(){
        StringBuffer str = new StringBuffer();
        str.append("id="+id);

        if (nodeFlat != null){
            str.append(" , nextNode=").append(nodeFlat.getId());
        }

        System.out.println(str);
    }

}

# 利用单向链表完成节点增删改查


/**
 * 链表的基本实现
 */
public class SingleLinkList {

    private LinkNodeFlat firstNode;

    /**
     * 添加链表节点元素
     * @param id
     */
    public void insertFirst(int id){
        //存放节点本身的数据
        LinkNodeFlat newLinkNode = new LinkNodeFlat(id);
        // 存放下一个节点的对象引用
        newLinkNode.setNodeFlat(firstNode);
        firstNode = newLinkNode;
    }

    /**
     * 移除链表中第一个节点
     * @return
     */
    public LinkNodeFlat removeFirst(){
        LinkNodeFlat temp = firstNode;
        // 移除第一节点,第一个节点后的节点成为新的第一节点
        firstNode = firstNode.getNodeFlat();
        return temp;
    }

    /**
     * 查找指定节点
     * @param id
     * @return
     */
    public LinkNodeFlat find(int id){
        LinkNodeFlat node = firstNode;
        //从第一个节点向下查找
        while(node.getId()!=id){
            if(node.getNodeFlat() == null){
                    return null;
            }else{
                // 获取链表下一个节点对象
                node = node.getNodeFlat();
            }
        }
        return node;
    }

    /**
     * 移除指定的节点
     * @param id
     * @return
     */
    public LinkNodeFlat remove(int id){
        LinkNodeFlat currentNode = firstNode;
        LinkNodeFlat previousNode = firstNode;
        //从第一个节点向下查找需要删除的结点
        while(currentNode.getId() != id){
            if(currentNode.getNodeFlat() == null){
                return null;
            }else{
                //如果ID不相等,当前节点更新为下一个待比较节点的前驱节点
                previousNode = currentNode;
                //当前节点的下一个节点变成下一个待比较的节点
                currentNode = currentNode.getNodeFlat();
            }
        }

        // 如果移除的节点就是第一个节点,则第一节点后的节点成为新的第一节点
        if(currentNode.equals(firstNode)){
            firstNode = firstNode.getNodeFlat();
        }else{
            // 前驱节点的下一个节点,设置为被删除节点的下一个节点
            previousNode.setNodeFlat(currentNode.getNodeFlat());
        }

        return currentNode;
    }

    /**
     * 打印链表节点数据
     */
    public void printNodeList(){
        System.out.println("-----思维的持续-----");
        LinkNodeFlat tempNode = firstNode;
        while(tempNode!=null){
            tempNode.printLink();
            // 获取链表下一个节点对象
            tempNode = tempNode.getNodeFlat();
        }
    }
    
    public static void main(String[] args) {
        SingleLinkList linkList = new SingleLinkList();

        linkList.insertFirst(7);
        linkList.insertFirst(2);
        linkList.insertFirst(5);
        linkList.insertFirst(9);

        linkList.printNodeList();
        linkList.removeFirst();
        linkList.printNodeList();

        LinkNodeFlat result = linkList.find(5);
        System.out.println("result:");
        result.printLink();
        linkList.printNodeList();

        linkList.remove(5);
        linkList.printNodeList();
    }
}

4、禅定时刻

单向链表在表头插入和删除操作效率很高,对于链表来说就是修改指针的引用,时间复杂度为常量O(1)。查找功能时间复杂度为O(N),比数组要快,链表操作不需要移动和复制数据。

原文地址:https://www.cnblogs.com/swdcx/p/12693150.html