Java算法入门-数组&链表&队列

算法就是解决问题的步骤,在一般的项目中可能用不上,但是一旦涉及到高并发,高性能时,就不得不考虑算法的优劣。

设计原则和特性

设计原则:正确性,可读性,健壮性,高效率和低存储

特性:有穷性,确定性,可行性,有输入,有输出。

算法题入门体验

如何判断是一个数是2的整数次幂?常规方法使用循环,但是在学习了二进制的基础知识后,发现可以使用模运算来实现。

 1 import java.util.Scanner;
 2 
 3 public class base {
 4 
 5     public static void main(String[] args) {
 6         /**
 7          * 算法入门,如何判断一个数是否为2的整数次幂,即是否为2^n
 8          * 如果不用算法就可以使用循环来实现
 9          * 如果使用算法,就可以考虑二进制的与运算
10          */
11         Scanner scan = new Scanner(System.in);
12         System.out.println("请输入需要计算的数字:");
13         int num = scan.nextInt();
14         method2(num);
15 
16     }
17 
18     /**
19      * 使用循环来实现
20      *
21      * @param n
22      */
23     public static void methon1(int n) {
24         while(true){
25             n=n/2;
26             if(n==2||n==1){
27                 break;
28             }
29         }
30         if(n==2){
31             System.out.println("这个数是2的整数次幂");
32         }else{
33             System.out.println("这个数不是2的整数次幂");
34         }
35     }
36 
37     /**
38      * 使用二进制与运算来实现
39      * @param n
40      */
41     public static void method2(int n){
42         /**
43          * 2的二进制10 1的二进制01 高位补齐
44          * 4的二进制100 3的二进制011 高位补齐
45          * 8的二进制1000 7的二进制0111 高位补齐
46          * ...
47          */
48         int m=n&(n-1);
49 
50         if(m==0){
51             System.out.println("这个数是2的整数次幂");
52         }else{
53             System.out.println("这个数不是2的整数次幂");
54         }
55 
56     }
57 }

控制台输出情况

时间复杂度&空间复杂度

评价算法的两个重要的指标为时间复杂度和空间复杂度。

时间复杂度:运行一个程序需要的时间,一般用O()表示,一般有如下几种,具体可以参考代码。

(1)常数型,能确定循环的次数,一般为O(1)

(2)线性型,循环次数不确定,并且没有嵌套循环等,一般表示O(N)

(3)对数型,参考代码,一般表示为log(N)

(4)嵌套型,参考代码循环嵌套,一般表示为O(N^2)

注意使用时间复杂度表达式时会省略低指数位,省略常数。

import java.util.ArrayList;
import java.util.List;

public class OCTest {

    public static void main(String[] args) {
        /**
         * 时间复杂度计算方法
         */

        //常数型
        int n=0; //O(1)
        int m=n+1; //O(1)
        for (int i = 0; i < 100; i++) {
            //有确定循环数目的,时间复杂度也是O(1)
        } //O(1)

        //线性型
        for (int i = 0; i < m; i++) {
            //循环次数不确定,就是线性型
        } //O(m)

        //对数型
        int c=1;
        while(c<=n){
            c=c*2;
            //循环结束就是2^m=n,这样使用高中数学知识就知道,m=log2^n,循环次数就是对数形式,在算法中就是写成log(n)
        } //O(log(n))

        //对数型
        for (int i = 0; i < n; i++) {
            int d=1;
            while(d<=n){
                d=d*2;
            }
        } //参考上面的例子,时间复杂度就是O(n*log(n))

        //下面嵌套的类型
        for (int i = 0; i <n ; i++) {
            for (int j = i; j < n; j++) {
                //当i=0,内存循环次数n次
                //当i=1,内存循环次数n-1
                //...
                //当i=n-1,内存循环次数为1
                //总的次数为上述等差数列之和n(n+1)/2,算法中去掉常数,只保留最高位后,时间复杂度变成O(n^2)
            }
        } // O(n^2)

        /**
         * 空间复杂度,表示占用内存
         */
        int j=0; //O(1)
        List<Integer> list=new ArrayList<Integer>();//默认容量大小为10,O(10)

    }
}

空间复杂度:运行一个程序所需要的内存,一般用OOM表示。

数据结构

数据结构是计算机存储和组织数据的方式,指相互之间存在一种或者多种特性关系的数据元素的集合。通常情况下,精心设计的数据结构可以带来更高的运行或者存储效率,如Btree用于MySql。数据结构跟高效的检索算法和索引技术有关,其中常见的数据结构有List,Set,Map和Queue,具体可以参考自己写的博客,持续添加中。

(1)List

 1 import java.util.ArrayList;
 2 import java.util.LinkedList;
 3 import java.util.List;
 4 import java.util.Vector;
 5 
 6 public class ListTest {
 7 
 8     public static void main(String[] args) {
 9         /**
10          * 数组和链表
11          */
12 
13         //List
14         List<Integer> list=new ArrayList<Integer>();//底层是数组实现,是线程不安全的,访问快
15 
16         List<Integer> list1=new LinkedList<Integer>();//底层是一个链表,删除插入快
17 
18         //vector
19         Vector<Integer> vector=new Vector<Integer>();//底层是一个数组,是线程安全的,多线程一般使用这个,但是性能相应的有损失
20     }
21 }

(2)Set

 1 public class SetTest {
 2 
 3     public static void main(String[] args) {
 4         /**
 5          * Set,主要用来去重的,Java有三种实现方式
 6          * 1 HashSet:去重的,去重后元素的顺序和插入的不一样
 7          * 2 TreeSet:排序的,底层数据结构为红黑树
 8          * 3 LinkedHashSet:维护了一个链表,保持插入和输出后的顺序一致
 9          */
10     }
11 }

(3)队列

 1 public class QueueTest {
 2 
 3     public static void main(String[] args) {
 4         /**
 5          * queue队列,用于等待队列,排队场景,如果一个系统流量高,需要做排队系统
 6          * MQ,消息队列
 7          *
 8          *
 9          * PriorityBlockingQueue:优先队列,如果实现一个排队场景,如有vip用户,可以让vip排在前面
10          * 其他比较常用的队列有:
11          * ArrayBlockingQueue 基于数组的阻塞队列,有界,不担心爆内存,take()一直会阻塞到有数据为止,可以用在高并发场景
12          * LinkedBlockingQueue 无界的队列,可能会爆内存
13          *
14          * DelayQueue 延迟队列
15          */
16 
17     }
18 }

常见数据结构优缺点

 

博客地址:

(1)https://www.cnblogs.com/youngchaolin/p/11032616.html 栈队列数组链表和红黑树

(2)https://www.cnblogs.com/youngchaolin/p/11028365.html Collection集合

(3)https://www.cnblogs.com/youngchaolin/p/10463887.html 二进制

转载于:https://www.cnblogs.com/youngchaolin/p/11026368.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值