zoukankan      html  css  js  c++  java
  • Java基础随笔2

    继续上回:

    ————————————————————————————————————————————————————————————————————————————————

    以下部分转自:https://github.com/crossoverJie/Java-Interview/blob/master/MD/LinkedList.md

    LinkedList 底层分析

    如图所示 LinkedList 底层是基于双向链表实现的,也是实现了 List 接口,所以也拥有 List 的一些特点(JDK1.7/8 之后取消了循环,修改为双向链表)。

    新增方法

        public boolean add(E e) {
            linkLast(e);
            return true;
        }
         /**
         * Links e as last element.
         */
        void linkLast(E e) {
            final Node<E> l = last;
            final Node<E> newNode = new Node<>(l, e, null);
            last = newNode;
            if (l == null)
                first = newNode;
            else
                l.next = newNode;
            size++;
            modCount++;
        }

    可见每次插入都是移动指针,和 ArrayList 的拷贝数组来说效率要高上不少。

    查询方法

        public E get(int index) {
            checkElementIndex(index);
            return node(index).item;
        }
        
        Node<E> node(int index) {
            // assert isElementIndex(index);
    
            if (index < (size >> 1)) {
                Node<E> x = first;
                for (int i = 0; i < index; i++)
                    x = x.next;
                return x;
            } else {
                Node<E> x = last;
                for (int i = size - 1; i > index; i--)
                    x = x.prev;
                return x;
            }
        }

    由此可以看出是使用二分查找来看 index 离 size 中间距离来判断是从头结点正序查还是从尾节点倒序查。

    • node()会以O(n/2)的性能去获取一个结点
      • 如果索引值大于链表大小的一半,那么将从尾结点开始遍历

    这样的效率是非常低的,特别是当 index 越接近 size 的中间值时。

    总结:

    • LinkedList 插入,删除都是移动指针效率很高。
    • 查找需要进行遍历查询,效率较低。

    ————————————————————————————————————————————————————————————————————————————————————————————

    LinkedList内容较为简单,没什么特别难得内容。查找时主要使用的是二分查找,这里顺便总结以下相关的查找算法。

    1.顺序查找(最无脑查找)适合于存储结构为顺序存储或链接存储的线性表,顺序查找的时间复杂度为O(n)。

    int SequenceSearch(int a[], int value, int n)
    {
        int i;
        for(i=0; i<n; i++)
            if(a[i]==value)
                return i;
        return -1;
    }

    2.二分查找

    元素必须是有序的,如果是无序的则要先进行排序操作,期望时间复杂度为O(log2n);

    //二分查找,直接对半
    int BinarySearch1(int a[], int value, int n)
    {
    int low, high, mid;
    low = 0;
    high = n-1;
    while(low<=high)
    {
    mid = (low+high)/2;
    if(a[mid]==value)
    return mid;
    if(a[mid]>value)
    high = mid-1;
    if(a[mid]<value)
    low = mid+1;
    }
    return -1;
    }

    //二分查找,递归版本
    int BinarySearch2(int a[], int value, int low, int high)
    {
    int mid = low+(high-low)/2;
    if(a[mid]==value)
    return mid;
    if(a[mid]>value)
    return BinarySearch2(a, value, low, mid-1);
    if(a[mid]<value)
    return BinarySearch2(a, value, mid+1, high);
    }

    3. 插值查找

    基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找。查找成功或者失败的时间复杂度均为O(log2(log2n))。

    //插值查找
    int InsertionSearch(int a[], int value, int low, int high)
    {
    int mid = low+(value-a[low])/(a[high]-a[low])*(high-low);
    if(a[mid]==value)
    return mid;
    if(a[mid]>value)
    return InsertionSearch(a, value, low, mid-1);
    if(a[mid]<value)
    return InsertionSearch(a, value, mid+1, high);
    }

    先列出三个简单的查找,后面重学数据结构和算法的时候再记录其他的树查找、哈希查找等等。

  • 相关阅读:
    Javascript的二进制数据处理学习 ——nodejs环境和浏览器环境分别分析
    ISO日期格式标准,浏览器到服务器到mysql中的时区
    开始学nodejs —— 调试篇
    TCP三次握手的正确使用姿势
    详解Javascript中正则表达式的使用
    浏览器HTTP缓存原理分析
    seajs3.0.0源码分析记录
    用spm2构建seajs项目的过程
    IIS7禁用单个静态文件的缓存配置方法
    jsp之EL表达式
  • 原文地址:https://www.cnblogs.com/Aurel1ano/p/9185301.html
Copyright © 2011-2022 走看看