java数据结构和算法学习笔记

第一章 什么是数据结构和算法

数据结构的概述

数据结构是指 数据再计算机内存空间或磁盘空间中的组织形式

1.数据结构的特性

数据结构 优点 缺点
数组 插入快,如果知道下标可以快速存取 查找和删除慢  大小固定
有序数组 比无序数组查找快   插入和删除慢 大小固定
后进先出 存取其他项很慢
队列 先进先出 存取其他项很慢
链表 插入和删除快 查找慢
二叉树 查找,插入,删除都快(如果保持平衡) 删除算法复杂
红黑树 查找,插入,删除都快 树总是是平衡的 算法复杂
2-3-4树 查找,插入,删除都快 树总是平衡的 类似的数对磁盘存储有用 算法复杂
哈希表 如果key已知则存取快,插入快 删除慢 如果key不知存取慢 空间利用不足
插入 删除快,对最大数据存取快 对其他项存取慢
实现世界建模 有些算法慢 且 复杂

算法概述 

算法是完成特定任务的过程

database 数据库

record 记录

field 字段

key 关键字

java基本数据类型

int ,short, char ,byte, long ,double, float,boolean

java数据结构和算法学习笔记

 java 数据结构的类库

java.until.*;

第二章 数组

1.有序数组二分法查找

java数据结构和算法学习笔记

public class SortArray {
    private int[] values = {2, 11, 44, 55, 357,358,400,414,505};
    //查找某值得索引
    private int find(int searchValue) {
        //|----------------------|
        //lower-->       <--upper
        int lowerBound = 0;
        int upperBound = values.length - 1;

        int current;

        while (true) {
            current = (lowerBound + upperBound) / 2;
            //值判断
            if(values[current]==searchValue){
                return current;
            }else if(lowerBound>upperBound){
                //索引判断
                return -1;//can't find 跳出循环
            }else {
                if(values[current]>searchValue){
                    //<---  upper (upper向内移动)
                    upperBound=current-1;
                }else {
                    //lower--->  (lower向内移动)
                    lowerBound=current+1;
                }
            }

        }
    }

    @Test
    public void test_find() {
        System.out.println(find(44));
        System.out.println(find(358));
        System.out.println(find(111));
    }
}

  

二分法查找与 log(N)成正比

java数据结构和算法学习笔记

大 O 表示法 不要常数

java数据结构和算法学习笔记

O(1)是优秀

java数据结构和算法学习笔记 性能良好

O(N) 性能一般

java数据结构和算法学习笔记性能较差

大O时间图(时间受数据项个数影响):

java数据结构和算法学习笔记

无序数组 快速插入   查找删除慢

有序数据 可以使用二分法查找

 第三章  简单排序

简单排序包括

  1. 冒泡排序
  2. 选择排序
  3. 插入排序

一般的排序 方法 (CAS : compare and swap)

1.比较两个数据项

2.交换两个数据项,或复制其中一项

冒泡排序

冒泡排序就是 比较相邻  大的往右冒泡

1.比较两个队员

2.如果左边的大 则交换位置

3.向右移一个位置 一次比较下面两个

4.一直比较下去。。。。

(每个的左边 和其右边进行比较)

java数据结构和算法学习笔记

。。。。。。

。。。。。。

java数据结构和算法学习笔记

冒泡排序第一趟 (挑出最大值)

冒泡排序java代码

bubble [ˈbəbəl] 冒泡

public class BubbleSort {

    private int[] buildIntArray(int size){
        int[] arr=new int[size];
        for(int i=0;i<size;i++){
            arr[i]= RandomUtils.nextInt(1,100);
        }
        return arr;
    }
   /*
    冒泡排序
    大的值往右冒泡
    */
    public void bubble(int[] arr){
         int out,in,temp;
        //第一趟 最大的已经冒泡到最右边, 所以第二趟不用再排。 减掉 out--
        for(out=arr.length-1;out>0;out--){
            //从左到右依次冒泡 所以 从0 依次比较
            for(in=0;in<out;in++){
                //往右冒泡 若左边大于右边 冒泡
                if(arr[in]>arr[in+1]){
                    temp=arr[in+1];
                    arr[in+1]=arr[in];
                    arr[in]=temp;
                }
            }
        }
    }

    @Test
    public void testSort(){
        int []arr=buildIntArray(9);
        System.out.println(Arrays.toString(arr));
        bubble(arr);
        System.out.println(Arrays.toString(arr));
    }
}

冒泡排序的 时间级别

第一趟 需要比较  n-1次

第二趟  需要比较  n-2次 

第三趟  需要比较  n-3次

。。。。。

=n(n-1)/2;

约为 N的平方

所以冒泡排序的时间复杂度 为   java数据结构和算法学习笔记

 选择排序

选择排序改进了冒泡排序

选择排序: 就是查找选择最小值 放在最左边,这样左边的就排好序了

java数据结构和算法学习笔记

选择排序java代码

public class SelectSort {
    private int[] buildIntArray(int size) {
        int[] arr = new int[size];
        for (int i = 0; i < size; i++) {
            arr[i] = RandomUtils.nextInt(1,100);
        }
        return arr;
    }

    /*
    选择排序
    选出最小的放在左边
    */
    private void select(int[] arr) {
        int out, in, temp;
        //左边是排好序的 不用排了 所以out++
        for (out = 0; out < arr.length - 1; out++) {
           //out 左边是排好了的  比较 out以后的 
            for (in = out + 1; in < arr.length; in++) {
                //out是左边的值,in是右边的值 因为 in=out+1
                //如果 右边的值小  把它交换到左边
                if (arr[in] < arr[out]) {
                    temp = arr[in];
                    arr[in] = arr[out];
                    arr[out] = temp;
                }
            }
        }
    }

    @Test
    public void testSort() {
        int[] arr = buildIntArray(9);
        System.out.println(Arrays.toString(arr));
        select(arr);
        System.out.println(Arrays.toString(arr));
    }
}

  选择 排序  时间复杂度 java数据结构和算法学习笔记

但是选择排序的速度快于冒泡排序 因为它进行的交换次数少;

插入排序

插入排序 一般情况下 比冒泡排序快一倍 ,比选择排序还要快一点

采用 局部有序 的方法

java数据结构和算法学习笔记

java代码

public class InsertSort {
    private int[] buildIntArray(int size) {
        int[] arr = new int[size];
        for (int i = 0; i < size; i++) {
            arr[i] = RandomUtils.nextInt(0,100);
        }
        return arr;
    }

    public void insert(int[] arr){
        int in,out;
        //外围的 循环次数 逐渐增加, 因为 左边排好的个数逐渐增加
        for(out=1;out<arr.length;out++){
            int temp=arr[out];//被标记的值,要排序的值
            in=out;//和左边已经排好的值 进行比较
            //从最大值 依次向左 逐个比较
            // 如果 左边的最大值 大于 temp ,再往左 找个小的值 和 temp比较
            //while 没我大 排到后面去
            while (in>0&&arr[in-1]>=temp){
                arr[in]=arr[in-1];
                --in;
            }
           arr[in]=temp;
        }
    }
    @Test
    public void testSort() {
        int[] arr = buildIntArray(9);
        System.out.println(Arrays.toString(arr));
        insert(arr);
        System.out.println(Arrays.toString(arr));
    }
}

  插入排序的时间复杂度也是 java数据结构和算法学习笔记

第四章 栈和队列

受限访问 ,更加抽象 作为构思算法的辅助工具

栈(stack)  

后进先出

栈只允许访问一个数据项,即最后插入的数据项。移除第一个数据项后 ,才可以访问第二个数据项。

  1. 用栈来检测 源程序中的  小括号,大括号 是否匹配
  2. 用栈来辅助遍历树的节点
  3. 微处理器运用栈的体系架构

用数组实现一个简单的栈

peek [pēk] :窥视

public class StackA {
    private int[] arr;
    private int max;
    private int top;

    public StackA(int max) {
        this.max = max;
        this.arr=new int[max];
        this.top=-1;
    }

    public void push(int v){
        arr[++top]=v;
    }

    public int pop(){
        return arr[top--];
    }
    /*
    Look at the obj at the top of stack  without remove it
    */
    public int peek(){
        return arr[top];
    }

    public boolean isEmpty(){
        return top==-1;
    }

    public boolean isFull(){
        return top==max-1;
    }

}

测试

 public void test(){
        StackA stackA=new StackA(7);
        stackA.push(1);
        stackA.push(2);
        stackA.push(3);
        stackA.push(4);
        stackA.push(5);

        while (!stackA.isEmpty()){
            System.out.println(stackA.pop());
        }
    }

  

写个demo检测 输入内容的 括号是否正确

bracket [ˈbrakit] : 括号

public class Bracket {
    private String input;

    public Bracket(String input) {
        this.input = input;
    }

    public void check() {
        if (StringUtils.isNotBlank(input)) {
            StackA stackA = new StackA(input.length());
            for (int i = 0; i < input.length(); i++) {
                char c = input.charAt(i);
                switch (c) {
                    case '{':
                    case '[':
                    case '(':
                        stackA.push(c);
                        break;
                    case '}':
                    case ']':
                    case ')':
                        if (!stackA.isEmpty()) {
                            char store = (char) stackA.pop();
                            if ((c == '}' && store != '{')
                                    || (c == ']' && store != '[')
                                    || (c == ')' && store != '(')
                                    ) {
                                System.out.println("Error " + c + " at " + i);
                                return;
                            }
                        } else {
                            System.out.println("Error " + c + " at " + i);
                            return;
                        }
                        break;
                    default:
                        break;
                }
            }
            if (!stackA.isEmpty()) {
                System.out.println("Error no bracket match with " + (char) stackA.peek());
            }
        }
    }
}

测试

public void test(){
       Bracket bracket=new Bracket("test(just test}");
       bracket.check();
       bracket=new Bracket("test :just test {");
       bracket.check();
    }

运行结果

java数据结构和算法学习笔记

  

  

  

上一篇:[译]Why do people write #!/usr/bin/env python on the first line of a Python script?


下一篇:数据结构(逻辑结构,物理结构,特点) C#多线程编程的同步也线程安全 C#多线程编程笔记 String 与 StringBuilder (StringBuffer) 数据结构与算法-初体验(极客专栏)