Java数据结构、算法和集合

一:java数据结构和算法

导图:

1.相关概念点:

  1)数组结构:数组是顺序的存储结构,也就是连续的内存空间。特点:查询快,增删慢。

  2)链表结构:链表是链式的存储结构,是指内存空间离散排列的。链表通过指针来连接元素与元素,数组则是把所有元素按次         序依次存储特点:查询慢,增删快。

  3)栈结构:是一种运算受限的线性表。后进先出的特点,基本操作有进栈和出栈。

  • 其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。
  • 向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;
  • 从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素

       
  4)队列结构:队列也是一种操作受限制的线性。先进先出的特点。(消息中间节队列的本质)。尾部添加、头部删除。类似生活的排队。

  5)树结构:

      *二叉搜索树:

         是指一棵空树或者具有下列性质的二叉树:

         若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
         若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
         任意节点的左,右子树也分别为二叉搜索树;
         没有键值相等的节点。

      *二叉平衡树:

         可以是空树, 假如不是空树,任何一个结点的左子树与右子树都是平衡二叉树,并且高度之差的绝对值不超过1

      *红黑树:

       五个性质:
      性质一:节点是红色或者是黑色;
      性质二:根节点是黑色;
      性质三:每个叶节点(NIL或空节点)是黑色;
      性质四:每个红色节点的两个子节点都是黑色的(也就是说不存在两个连续的红色节点); 
      性质五:从任一节点到其没个叶节点的所有路径都包含相同数目的黑色节点;

      ***
      这五条性质约束了红黑树,可以通过数学证明来证明,满足这五条性质的二叉树可以将查找删除维持在对数时间内(T(n) =          O(log n),)。

     红黑树操作:
     变色,
     左旋:
     右旋:
     旋转的目的是将节点多的一支出让节点给另一个节点少的一支,旋转操作在插入和删除操作中经常会用到

  6)图结构:是比树结构更复杂的一种非线性数据结构(地铁网络)。

2.算法:

  1)冒泡排序:

**************************************************************************************

①基本思想:两个数比较大小,较大的数下沉,较小的数冒起来。

②算法描述:

比较相邻的元素。如果第一个比第二个大,就交换它们两个;

对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;

针对所有的元素重复以上的步骤,除了最后一个;
外层for循环表示比较轮数,范围是[0,arr.length-1),总共比较了length-1轮

内层for循环表示第 i 轮比较的次数,范围是[0,arr.length-1-i)

每一轮都会产生一个最值(最大值或最小值),则下一轮就少比较一次

外层for循环控制比较的总轮数,该循环是以内层for循环的变量 j 作为数组的下标进行比较

/**
 * @author jyroy
 * 冒泡排序常规版
 */
public class BubbleSortNormal {
    public static void main(String[] args) {
        int[] list = {3,4,1,5,2};
        int temp = 0; // 开辟一个临时空间, 存放交换的中间值
        // 要遍历的次数
        for (int i = 0; i < list.length-1; i++) {
            System.out.format("第 %d 遍:\n", i+1);
            //依次的比较相邻两个数的大小,遍历一次后,把数组中第i小的数放在第i个位置上
            for (int j = 0; j < list.length-1-i; j++) {
                // 比较相邻的元素,如果前面的数小于后面的数,就交换    逆序
               /* if (list[j] < list[j+1]) {
                    temp = list[j+1];
                    list[j+1] = list[j];
                    list[j] = temp;
                }*/
                // 比较相邻的元素,如果前面的数小于后面的数,就交换    顺序
                if (list[j] > list[j+1]) {

                    temp = list[j];
                    list[j] = list[j+1];
                    list[j+1] = temp;

                }
                System.out.format("第 %d 遍的第%d 次交换:", i+1,j+1);
                for(int count:list) {
                    System.out.print(count);
                }
                System.out.println("");
            }
            System.out.format("第 %d 遍最终结果:", i+1);
            for(int count:list) {
                System.out.print(count);
            }
            System.out.println("\n#########################");
        }
    }
}

**************************************************************************************

  2)  插入排序:

**************************************************************************************


^.依次拿当前元素和其后面的元素比较大小,满足条件就互换值
^.public static int[] shunxu(int[] arr){
    int len = arr.length;
    int temp = 0;
    
    for (int i = 0; i < len-1; i++) {
        for (int j = i+1; j < len; j++) {
            if(arr[i] > arr[j]){
                temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr;
}
arr[i]是当前元素,范围是[0,arr.length-1)

arr[j]是当前元素后面的元素,范围是[i+1,arr.length)

**************************************************************************************

  3)选择排序:

**************************************************************************************

^.假设前面的数字是有序的,依次拿当前元素与前面元素做比较,满足条件就互换值

^.public static int[] charu(int[] arr){
    int len = arr.length;
    int temp = 0;
    
    for (int i = 1; i < len; i++) {
        for (int j = i; j > 0; j--) {
            if(arr[j] > arr[j-1]){
                temp = arr[j];
                arr[j] = arr[j-1];
                arr[j-1] = temp;
            }else{
                break;
            }
        }
    }
    return arr;
}
外层for循环控制轮数,范围是[1,arr.length)

从第2个数字开始,与前面的数字比较,满足条件就互换值,否则就放到当前位置(代码中有break)

**************************************************************************************

3)时间复杂度:

在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级。算法的时间复杂度,也就是算法的时间量度,记作:T(n)= O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐近时间复杂度,简称为时间复杂度。其中f(n)是问题规模n的某个函数。

 

二.集合

导图:

 

1.List集合:

ArrayList:

  1)数组结构,查询快,增删慢。线程不安全,效率高。

   2)动态数组,容量能扩充,是一个数组队列,提供了,增删改差遍历等操作,可以通过元素序号,实现元素的快速随机访问。

  3)可以被clone,支持序列化。

LinkedList:

   1)是一个双向链表结构。2)能被clone,支持序列化。3)增删快,查询慢,线程不安全。4)和ArrayList一样支持三种遍历方式(普通for,增强for,迭代器)

vector:可实现自动增长的对象数组,可以往其中随意插入不同类的对象,即不需顾及类型也不需预先选定向量的容量,并可以方便地进行查找,线程安全。

2.Set集合:

HashSet:1)底层是HashMap实现。2)Hash表结构(散列表:数组+链表结构)3)不能包含重复的对象。4)不能保证元素顺序

5)不是同步,线程不安全。6)集合元素可以是null,但只能放入一个null。

TreeSet:默认自然排序,是二叉树实现,通过equals或CompareTo(返回值是否为0判断)方法比较元素是否相等。不允许放入null值,是线程不安全。

LinkedHashSet:一种有序的Set集合(遍历顺序和插入顺序是一致的),底层是LinkedHashMap

3.Map集合:

HashMap:1)链表+数组+红黑树结构(jdk1.8引入,提高了HashMap的性能)。2)线程不安全,key-value形式存储数据,允许null key ,null value.3)负载因子0.75当元素超过0.75*HashMap的长度时便会进行resize(默认大小为16,扩容大小为2的指数)。

TreeMap:是一个有序的key-value集合,它是通过红黑树实现的,能被克隆,支持序列化,线程不安全。

LinkedHashMap:HashMap的子类,双重链表的HashMap,存取和取出都是有序的,线程不安全。

HashTable:线程安全,效率低,不允许null键,null值。默认大小为11,扩容公式:arr*2+1,使用Enumeration遍历

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值