精华内容
下载资源
问答
  • 篇我们分析了ArrayList的源码部分,基本了解了ArrayList实际是数组的增删改查进行了包装,而且支持动态扩容。但是ArrayList和数一样,同样存在查找快,增删慢的特点 。有没有容器更适合用来存在和删除的...

    上一篇分析了ArrayList的源码部分,基本了解了ArrayList实际是对数组的增删改查进行了包装,而且支持动态扩容。但是ArrayList和数组一样,同样存在查找快,增删慢的特点。

    有没有容器更适合用来插入和删除的元素呢,链表就是其中一种适合增删的数据结构,而LinkedList就是链表结构应用之一。

    在研读源码之前,先来了解链表这种数据结构,常见的链表有单向链表,双向链表,循环链表,链表的结构包括:头节点,尾节点,和维护节点关联关系的指针。和数组相比:

    • 存储空间:数组对于内存的要求比较高,需要一块连续的内存空间来存储,如果你申请的一个100M大小的数组,当内存中没有连续的,足够大的存储空间时,即便剩余内存可用空间大于100MB,申请仍然会是失败的。而链表是一种松散的数据结构,对内存没有连续性要求,节点是通过指针关联的;
    • 性能:数组特点查询快,增删慢,查询是根据数据下标,增删可能涉及耗时的数据搬移;链表是查询慢,增删快,查询需要从头来遍历链表,增删之需要修改节点之间的指针关系;

    继承体系:

    LinkedList继承了抽象类AbstractSequentialList,实现了基本的容器操作方法,实现List接口,Deque接口,Cloneable接口,java.io.Serializable支持序列化

    public class LinkedList<E>
        extends AbstractSequentialList<E>
        implements List<E>, Deque<E>, Cloneable, java.io.Serializable

    变量组成:

    主要有三个成员变量,并且都是当前对象的属性,不支持序列化

    transient int size = 0;//当前链表大小
    
    transient Node<E> first;//当前链表首节点,首节点的特点:前躯指针为空,后继指针可为空或者指向下一个节点
    
    transient Node<E> last;//当前链表尾节点,尾节点的特点:前驱指针指向上一个节点,后继指针为null
    
    //transient关键字标记的成员变量不参与序列化过程。

    构造方法:相比于ArrayList,LinkedList只有两个构造方法,一个无参的构造方法,另一个是包含集合collection元素的列表。

    //无参构造方法
    public LinkedList() {
        }
    //包含指定collection元素的列表
    public LinkedList(Collection<? extends E> c) {
            this();
           //addAll方法先会把Collection转化成数组
            addAll(c);
        }

    在LinkedList中有一个重要的内部类也就是节点类Node.

        private static class Node<E> {
            E item;//当前存储元素
            Node<E> next;//下一个元素节点
            Node<E> prev;//上一个元素节点
    
            Node(Node<E> prev, E element, Node<E> next) {
                this.item = element;
                this.next = next;
                this.prev = prev;
            }
        }
    

    重点方法分析:

     在链表尾部添加元素方法:add(E e);

    在链表的尾部添加元素,分两种情况,当尾节点不为空时,说明链表中已存在数据,只需要在将当前链表的尾节点作为新节点的前驱指针,尾节点的后继指针指向新节点,新增节点作为尾节点;尾节点为空,也就是说,链表为空时,新加入的节点即使首节点也是尾节点。

        public boolean add(E e) {
            linkLast(e);
            return true;
        }
        //如果末尾节点为空,则新增元素为尾节点,否则将原尾节点的下一个元素节点指向新增元素
        //尾节点的特点:后继指针为null
        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++;//大小增加1
            modCount++;//修改次数增加1
        }

    在指定位置添加元素:add(int index, E element)

    首先校验插入的位置是否在链表中;判断插入的位置,如果插入位置在链表的末尾,则在链表末尾追加元素;否则通过二分查找先从首节点开始遍历,如果从未找到元素,则从尾节点开始遍历找倒序查找;将新节点追加到指定位置之前,修改指针指向。

        public void add(int index, E element) {
            //校验下标的合法性
            checkPositionIndex(index);
            //如果插入位置等于链表大小,那么就在文章末尾插入元素
            if (index == size)
                linkLast(element);
            else
                //在中间节点位置插入元素
                linkBefore(element, node(index));
        }
          //找到指定位置的节点,从这段代码中可以看出,找到指定位置的节点元素,
          //是要循环遍历这个链表,不过这里已经采用了二分查找优化了查找的算法
          Node<E> node(int 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;
            }
        }
        //插入新元素的方法
        void linkBefore(E e, Node<E> succ) {
            //获取旧元素的前驱节点
            final Node<E> pred = succ.prev;
            //获取新元素
            final Node<E> newNode = new Node<>(pred, e, succ);
            //将新元素的引用设置为旧元素的前驱节点
            succ.prev = newNode;
            //如果旧元素的前驱节点为空,则新增元素即为首节点;不为空,则旧元素的前驱节点的后驱节点设置为新元素
            if (pred == null)
                first = newNode;
            else
                pred.next = newNode;
            size++;//链表大小加1
            modCount++;//修改次数+1
        }

    获取指定位置的元素:get(int index),校验索引是否越界,通过二分查找遍历链表

        public E get(int index) {
            //校验索引是否越界
            checkElementIndex(index);
            return node(index).item;
        }
         //找到指定位置的节点,从这段代码中可以看出,找到指定位置的节点元素,
         //是要循环遍历这个链表,不过这里已经采用了二分查找优化了查找的算法    
         Node<E> node(int 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;
            }
        }

    修改固定位置的元素:set(int index, E element)  节点位置不变,只修改元素的值。

        public E set(int index, E element) {
            //校验索引合法性
            checkElementIndex(index);
            //获取指定位置的元素(同一个方法,不在赘述)
            Node<E> x = node(index);
            //获取旧的元素值
            E oldVal = x.item;
            //将新的元素值赋值给节点信息
            x.item = element;
            return oldVal;
        }

     清除链表:clear(),循环遍历,直到每个节点的关联关系都被打破。

    //编列所有元素,将对于的节点信息置为null,大小修改为0   
     public void clear() {
            for (Node<E> x = first; x != null; ) {
                Node<E> next = x.next;
                x.item = null;
                x.next = null;
                x.prev = null;
                x = next;
            }
            first = last = null;
            size = 0;
            modCount++;
        }

    默认删除的是首节点,返回删除元素:remove(),默认移除首节点的关联关系

        public E remove() {
            return removeFirst();
        }
        public E removeFirst() {
            final Node<E> f = first;
            if (f == null)
                throw new NoSuchElementException();
            return unlinkFirst(f);
        }
        //移除首节点,将首节点的下驱节点置为首节点
        private E unlinkFirst(Node<E> f) {
            // assert f == first && f != null;
            final E element = f.item;
            final Node<E> next = f.next;
            f.item = null;
            f.next = null; // help GC
            first = next;
            if (next == null)
                last = null;
            else
                next.prev = null;
            size--;
            modCount++;
            return element;
        }
    

    还有队列的的方法push(E e)和pop(),其实就是对首节点和尾节点的操纵,先进先出

        public void push(E e) {
            addFirst(e);
        }
        public void addFirst(E e) {
            linkFirst(e);
        }
        private void linkFirst(E e) {
            final Node<E> f = first;
            final Node<E> newNode = new Node<>(null, e, f);
            first = newNode;
            if (f == null)
                last = newNode;
            else
                f.prev = newNode;
            size++;
            modCount++;
        }
    
        public E pop() {
            return removeFirst();
        }
        public E removeFirst() {
            final Node<E> f = first;
            if (f == null)
                throw new NoSuchElementException();
            return unlinkFirst(f);
        }
        private E unlinkFirst(Node<E> f) {
            // assert f == first && f != null;
            final E element = f.item;
            final Node<E> next = f.next;
            f.item = null;
            f.next = null; // help GC
            first = next;
            if (next == null)
                last = null;
            else
                next.prev = null;
            size--;
            modCount++;
            return element;
        }

    总结看,LinkedList是一个更适合增删元素的容器,查找元素从需要遍历元素,采用二分查询算法,最坏情况时间复制度是O(logn),新删元素的时间复制度为O(1)。

    备注:JDK1.6之前为循环链表,JDK1.7以后取消循环,源码展示为JDK版本:1.8.0_241

    展开全文
  • 假设个分类问题数据集,有30个特征,为提高分类的准确率,或者出于汇报的要求(哪些特征,或者有可解释性意义的特征组合结果影响较大)需要特征进行分析和组合,不是PCA之类的降维,比如两个连续变量进行...
  • 思路: 使用分析函数row_number() over (partiion by ... order by ...)来进行分组编号,然后取分组标号值为1的记录即可。...order by则是指定在同一组进行编号时是按照怎样的顺序。 示例: 1 ...

    思路:

    使用分析函数row_number() over (partiion by ... order by ...)来进行分组编号,然后取分组标号值为1的记录即可。目前主流的数据库都有支持分析函数,很好用。

    其中,partition by 是指定按哪些字段进行分组,这些字段值相同的记录将在一起编号;order by则是指定在同一组中进行编号时是按照怎样的顺序。

    示例:

    1

    2

    3

    4

    5

    6

    select s.*  

    from 

        select *, row_number() over (partition by [重复字段] order by [唯一字段(一般使用主键)]) as group_idx  

        from table_name

    ) s

    where s.group_idx = 1

    展开全文
  • 本书第2版版内容进行了全面更新和修订,它将揭示回答这些问题的方法与技巧。你将学到如何获取、分析和汇总散落于社交网站(包括Facebook、Twitter、LinkedIn、Google+、 GitHub、邮件、网站和博客等)的数据,...
  • 2.不明显的数据,要进行数据挖掘来发现有用的知识 3.心智模型:大脑利用新信息的工具 4.当怀疑因果走向时,注重反向思考(B影响A) 5.混杂因素:演技对象的个人差异 怎样查清混杂因素:就自己正在研究的问题问...

    1.数据分析基本流程:
    确定问题-分解问题-评估-决策
    2.对不明显的数据,要进行数据挖掘来发现有用的知识
    3.心智模型:大脑利用新信息的工具
    4.当怀疑因果走向时,注重反向思考(B影响A)
    5.混杂因素:演技对象的个人差异
    怎样查清混杂因素:就自己正在研究的问题问自己一些常识性问题,借此想象这些变量是否会影响你的分析结果。
    6.控制组(对照组):
    一组体现现状的处理对象,未经过任何新的处理。

    分析工具:实验设计、最优化、图表、假设检验、贝叶斯规则·
    7.最优化问题: c表示约束条件:c1p1+c2p2=P(目标,期待的最大化对象)
    8.数据图形化的根本在于正确比较.
    散点图:发现因果关系
    9.伪证法(排除异质数据):剔除无法证实的假设—>对假设进行评级,不利证据越少的越排在前面。
    10.诊断性:能够帮助你评估各种假设的相对强度(存在支持假设和不利假设),证据和数据就具有诊断性。
    11.直接概率问题(贝叶斯)

    贝叶斯规则:在假设成立或者不成立的条件下看证据出现的几率。

    12.启发式:一种解决问题的方法,可能得出正确答案,但不保证得出最优化答案。最优化是最理想的情况。
    13.直方图:通过数据子集分析数据
    散点图:将不同变量放在一起比较(通常是一个点代表一个对象的不同变量)
    使用平均值图预测每个区间内的数值。(显示x轴上的每个区间相对应的Y轴的数值)
    14.回归分析:预测未来。算法:不同要求带来的不同结果,决策过程。
    相关性为1或者-1都有充足的理由使用回归线
    15.误差:外插法:用回归方程预测数据范围以外的数据值
    机会误差、残差:实际结果与预测结果之间的偏差

    展开全文
  • , 从始至终,数据分析者都在数据层面上思考问题,而不是拿着水彩笔和调色板在那里划作图,而计算机程序员则倾向于画点画线。Leland Wilkinson的著作在理论上改善了这种状况,他提出了一套图形语法,让我们在...
  • 实验的过程中,经常需要所采集的数据进行频谱分析,软件的选择计算速度影响挺大的。我在实验过程中,通常使用Origin7.5来进行快速傅里叶变换,因为方便快捷,计算之后,绘出来的图也容易编辑。但是当数据容量太...

    实验的过程中,经常需要对所采集的数据进行频谱分析,软件的选择对计算速度影响挺大的。我在实验过程中,通常使用Origin7.5来进行快速傅里叶变换,因为方便快捷,计算之后,绘出来的图也容易编辑。但是当数据容量太大,达到100M大小,这时候使用Origin7.5进行快速傅里叶变换,运算速度非常慢,甚至运算不出来。

    对大容量的数据进行快速傅里叶变换,我使用Matlab,运算速度比Origin7.5快很多。但是使用Matlab进行FFT时,需要进行一些小的处理,才能使运算结果与使用Origin7.5进行FFT时得到的结果保持一致。

    (1)首先介绍运用Origin7.5进行FFT的基本操作,

    选中数据后,点击“分析”,下拉菜单中出现“快速傅里叶变换FFT”,点击进入,这个时候会弹出对话框。对话框中,“FFT”下面的“Forward”和“Backward”是正变换和逆变换。“Spectrum”选择“Amplitude”或者选择“Power”,一个是幅度谱,一个是功率谱。其中功率谱是幅度谱的平方。

    点击对话中“Settings”按钮,弹出对话框。

    其中第四行“Sampling”设置为采样间隔,就是采样率的倒数。第一行的“Sampling”可以不用设置,第二行的“Real”为需要进行傅里叶变换的离散数据,数据一般是实数,故没有虚部,第三行的“Imaginar”不用设置。

    “Window Method”一般选择“Rectangular”,

    各个窗函数的表示式为:

    上述对话框中“Output

    Options”下面的选项,第一行为是否对FFT之后的幅度进行归一化,这个是要选择归一化的。第二行,表示式单边带,还是双边带,我一般选择单边带。第三行和相位相关。

    上述对话框中“Exponential Phase

    Factor”表示FFT是选择e-jwt还是ejwt,通常FFT算法是前者。

    上述这是完之后,就可以得到FFT之后的结果。

    关于Origin进行FFT原理,可以参考网页:

    (2)其次介绍运用Matlab进行FFT的基本操作,

    在使用Matlab进行FFT时,首先要搞清楚FFT的原理。离散傅里叶变换,需要输入数据必需是2n,当输入的数据不是时,则补零,使其满足2n。因此,在使用Matlab进行FFT时,首先是知道离散数据的个数,然后对其补零,之后才是FFT运算。

    在Matlab导入数据之后,我通常的做法是使用函数length对数据求大小,比如得到N,然后求解log2(N),比如是21.22。然后使用fft(data,222),之所以是222,是因为数据个数补零之后,数据个数是222。fft(data,222)得到的result就是通常的结果,这是个复数。对result求模,即通过函数abs(result)实现,得到的是幅度,这个时候得到的幅度谱和使用Origin得到的没有归一化的幅度谱是一致。但是,通常我们使用Origin是得到归一化的幅度谱,因此这里得到abs(result)之后,进行归一化,即abs(result)*2/222,在频率点零值处,归一化应该为abs(result)/222,频率点的设置为(0:

    222-1)*fs/222,其中fs是采样率。最后plot(f,

    abs(result)*2/222)就是最后的归一化的幅度,注意就是零值处的特殊处理。

    Origin作归一化处理的时候,并没有考虑零值和其他地方的不同,都是除以n/2

    使用Matlab得到FFT结果之后,就是导出数据,通常数据较大,使用一般的粘贴复制太慢或不行,我一般使用函数dlmwrite。导出的数据,再导入Origin画图,也比较方便。

    以上就是我计算FFT的方法,肯定有更好的方法。

    展开全文
  • 2.4 怎样表示个算法 24 2.4.1 用自然语言表示算法 24 2.4.2 用流程图表示算法 24 2.4.3 三种基本结构和改进的流程图 28 2.4.4 用N-S 流程图表示算法 29 2.4.5 用伪代码表示算法 30 2.4.6 用计算机语言表示算法 31 ...
  • 2.4 怎样表示个算法 24 2.4.1 用自然语言表示算法 24 2.4.2 用流程图表示算法 24 2.4.3 三种基本结构和改进的流程图 28 2.4.4 用N-S 流程图表示算法 29 2.4.5 用伪代码表示算法 30 2.4.6 用计算机语言表示算法 31 ...
  • 通过上篇文章《Appium Android Bootstrap源码分析之简介》我们bootstrap的定义以及其在appium和uiautomator处于个什么样的位置有了个初步的了解,那么按照正常的写书的思路,下个章节应该就要去看...
  • logistic 回归是二分响应变量进行建模。它的推广是多于两个类别的属性响应变量进行建模。这章我们将研究多类别模型。在学习之前我们先留 个问题:基线-类别logit模型该怎么写?基线-类别logit模型中 的表达式...
  • 数据运营思维导图

    2018-04-26 14:24:22
    大的营销事件作为节点单独标记,数据剔除出来单独进行分析 节点思路 如运营活动等 行为标记思路 将大动作的优化,大的项目上线及时标注在数据报表中 培养数据的敏感度 培养数据思维,从每天的各种数据报表开始...
  • 此队列按 FIFO(先进先出)原则元素进行排序。新元素插入到队列的尾部,队列检索操作则是从队列头部开始获得元素。 分析要点 是否线程安全? 数据结构是怎样的? 怎么实现阻塞和非阻塞插入和获取元素? 怎么实现...
  • 2019数据运营思维导图

    2019-03-29 21:34:09
    从多个维度拆分数据 对比思路 大的营销事件作为节点单独标记,数据剔除出来单独进行分析 节点思路 如运营活动等 行为标记思路 将大动作的优化,大的项目上线及时标注在数据报表中 培养数据的敏感度 培养数据思维,...
  • struct深入分析

    2010-06-21 17:18:00
    因为个大型的C/C++程序,势必要涉及一些(甚至大量)进行数据组合的结构体,这些结构体可以将原本意义属于个整体的数据组合在一起。从某种程度上来说,会不会用struct,怎样用struct是区别个开发人员是否具备...
  • 线性回归分析是一种统计方法,用于确定某个变量(或一组变量)另一个变量的影响。这个解释其实有点拗口,举个例子,我们知道,销售推广费用会影响到销售量,那具体是怎样的关系?如果要预测未来的数据,可以怎么做?...
  • 第7章 借助数据透视表不同的数据进行分析 155 7.1 使用多重合并计算数据区域 156 7.2 多重合并计算数据区域的数据透视表的详细分析 161 7.2.1 “行”字段 162 7.2.2 “列”字段 162 7.2.3 “值”字段 ...
  • 第7章 借助数据透视表不同的数据进行分析 155 7.1 使用多重合并计算数据区域 156 7.2 多重合并计算数据区域的数据透视表的详细分析 161 7.2.1 “行”字段 162 7.2.2 “列”字段 162 7.2.3 “值”字段 ...
  • 第7章 借助数据透视表不同的数据进行分析 155 7.1 使用多重合并计算数据区域 156 7.2 多重合并计算数据区域的数据透视表的详细分析 161 7.2.1 “行”字段 162 7.2.2 “列”字段 162 7.2.3 “值”字段 ...
  • 第7章 借助数据透视表不同的数据进行分析 155 7.1 使用多重合并计算数据区域 156 7.2 多重合并计算数据区域的数据透视表的详细分析 161 7.2.1 “行”字段 162 7.2.2 “列”字段 162 7.2.3 “值”字段 ...
  • 1.掌握顺序查找、折半查找及二叉排序树上查找的基本思想和算法实现,了解怎样对各种查找方法进行时间性能(平均查找长度)分析。 2.掌握各种排序方法的基本思想、排序过程、算法实现,能进行时间和空间性能的分析...
  • .窗口函数有什么用?在日常工作中,经常会遇到需要在每内排名,比如下面的...窗口函数,也叫OLAP函数(Online Anallytical Processing,联机分析处理),可以数据库数据进行实时分析处理。窗口函数的基本语法...
  • 实验原理: 1. 应用层协议 应用层协议(application layer protocol)定义了运行在不同端系统上的应用程序进程如何相互传递报文。 1)域名系统(Domain Name System,DNS):用于实现...4、传输过程和数据报文进行协议分析
  • 问题 117页8-3判定表中的年龄性别婚姻是如何对应后面符号的 判定表是用什么方式来进行判定的 问题1是不是要先画个条件取值表后再花判定表还有条件取值表属于数据字典吗条件取值表也是有关元素的定义和详细描述 ...
  • arff数据集全集(new)

    2018-12-10 16:32:20
    下面我们来这个文件的内容进行说明。 识别ARFF文件的重要依据是分行,因此不能在这种文件里随意的断行。空行(或全是空格的行)将被忽略。 以“%”开始的行是注释,WEKA将忽略这些行。如果你看到的“weather....
  • 数据结构 1800题》

    热门讨论 2012-12-27 16:52:03
    5.抽象数据类型的定义仅取决于它的一组__(1)_,而与_(2)_无关,即不论其内部结构如何变化,只要它的_(3)_不变,都不影响其外部使用。【山东大学 2001 三、3(2分)】 6.数据结构中评价算法的两个重要指标是...
  • 认知心理学将认知看成有信息的获取、分析、归纳、解码、储存、概念形成、提取和使用等系列阶段组成的按一定程序进行信息加工系统。 科学领域中,认知是包含注意力,记忆、产生和理解语言、解决问题、以及进行决策...

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 286
精华内容 114
关键字:

怎样对一组数据进行分析