• Java数据结构算法


    目录

     
      

    链表

      “数组”作为数据存储结构有一定的缺陷

    • 无序数组——搜索效率是低效的
    • 有序数组——插入效率低

      不管在哪种数组中删除效率都很低,创建数组后,大小不可改变

    线性数据结构

      

         

    为什么链表很重要?

    • 最简单的动态数据结构
    • 更深入的理解引用(或者指针)
    • 更深入的理解递归
    • 辅助组成其他的数据结构(图结构、哈希表、队列)

    链表 LinkedList

      数据储存在“节点(Node)”中,一个链节点是某个类的对象

      

      

      优点:真正的动态,不需要处理固定容量的问题(不用像数组new出来一片空间)

      缺点:不能随机访问(数组开辟的空间在内存上是连续的,可以通过下标计算出内存地址进行随机访问,而链表必须是顺序访问,由于依靠next一层一层连接,在计算机的底层,每一个节点对应的内存地址不同

    数组和链表的对比

      数组:最好用于索引有语意的情况(user[1])

      优点:快速查询

      数组:最好不用于索引有语意的情况

      链表:动态


    应用

    1、在链表头添加元素

      在数组中,在最后面添加元素是最方便的,因为有size在跟踪数组的最后一个元素

      但是链表恰恰相反,链表头添加元素,因为有head头结点,没有跟踪最后一个元素的结点

      

    public class LinkedList<E>{
    
        private class Node{
            public E e;
            public Node next;
    
            public Node(E e,Node next){
                this.e=e;
                this.next=next;
            }
    
            public Node(E e){
                this(e,null);
            }
    
            public Node(){
                this(null,null);
            }
        }
    
        private Node head;
        private int size;
    
        public LinkedList(){
            head=null;
            size=0;
        }
    
        //获取链表中元素个数
    
        public int getSize() {
            return size;
        }
    
        public boolean isEmpty(){
            return size==0;
        }
    
        //在链表头结点添加元素
        public  void addFirst(E e){
            Node node=new Node(e);
            node.next=head;
            head=node;
    
            //head=new Node(e);相当于上面三行
            size++;
        }
    }
    View Code

    2、在链表中间(末尾)添加元素

       在搜索为2的位置插入元素

      

       关键:找到添加结点的前一个节点

      注意:如插入到索引为0的节点后面,头结点没有前驱节点

      //在链表中间添加元素
        public void add(int index,E e){
            //判断索引的和发现
            if(index<0||index>size){
                throw new IllegalArgumentException("add failed,illegal index");
            }
            //如果在链表头添加,由于链表头没有前驱节点,需特殊处理
            if(index==0){
                addFirst(e);
            }else{
                Node pre=head;
                for (int i = 0; i <index-1 ; i++) {
                    //一直将前驱节点向前移,直到找到index位置的节点
                    pre=pre.next;
                    Node node=new Node(e);
                    node.next=pre.next;
                    pre.next=node;
    
                    //pre.next=new Node(e,pre.next);相当于上面三行
                    size++;
                }
            }
        }
    
        //在链表末尾添加元素
        public void addLast(E e){
            add(size,e);
        }
    View Code

     3、为链表设置虚拟头结点

      由于头结点没有前驱节点,在链表头结点和其他位置插入元素,会有所不同

      因此构建一个虚拟头结点为null,就不需要对头结点进行特殊处理,只需要找到待添加元素的前一个节点

      

        //在链表中间添加元素
        public void add(int index,E e){
            //判断索引的和发现
            if(index<0||index>size){
                throw new IllegalArgumentException("add failed,illegal index");
            }
            //如果在链表头添加,由于链表头没有前驱节点,需特殊处理
                Node pre=dummyHead;
                for (int i = 0; i <index; i++) {
                    //一直将前驱节点向前移,直到找到index位置的节点
                    pre=pre.next;
                    Node node=new Node(e);
                    node.next=pre.next;
                    pre.next=node;
    
                    //pre.next=new Node(e,pre.next);相当于上面三行
                    size++;
                }
        }
    
        //在链表末尾添加元素
        public void addLast(E e){
            add(size,e);
        }
    
        //在链表头结点添加元素
        public void addFirst(E e){
            add(0,e);
        }
    View Code

     4、链表

        //获得链表的第index(0-base)个位置的元素
        public E get(int index){
            //判断索引的合法性
            if(index<0||index>size){
                throw new IllegalArgumentException("add failed,illegal index");
            }
            Node cur=dummyHead.next;
            for (int i = 0; i <index ; i++) {
                cur=cur.next;
            }
            return cur.e;
        }
    
        //获取链表第一个元素
        public E getFirst(){
            return get(0);
        }
    
        public E getLast(){
            return get(size-1);
        }
    View Code
  • 相关阅读:
    mongo与node的两种连接方式 mongoskin && mongoclient 的基本使用
    promise 源码 简单分析
    node之 glob模块 相对路径绝对路径浅析
    webpack 多入口打包配置示例
    webpack 多入口打包分析
    MyEclipse8.5 以debug模式启动tomcat6.0服务器 报错cannot connect to vm。
    java开发bug 在启动Tomcat 6.0时发现第一条信息便是
    java 开发, jdk 1.6 官方下载地址
    电脑故障
    myeclipse添加源码支持
  • 原文地址:https://www.cnblogs.com/echola/p/11022302.html
Copyright © 2020-2023  润新知