基础数据结构与算法-数组,队列,链表,栈_Java

package edu.stack;

/**
 * @author: LHT
 * @date: 2020/12/13 11:38
 */
public class MyStack {

    String[] data = new String[1];
    int index;
    /**
     * 入栈
     *
     * @param value
     * @return
     */
    public int push(String value) {
        judgeSize();
        data[index] = value;
        index++;
        return 0;
    }

    /**
     * 判断是否需要扩容
     */
    private void judgeSize() {
        if (index >= data.length) {
            resize(2 * data.length);
        } else {
            if (index > 0 && index < (data.length / 2)) {
                resize(data.length / 2);
            }
        }
    }

    /**
     * 扩容或者收缩
     *
     * @param size
     */
    private void resize(int size) {
        String temp[] = new String[size];
        for (int i = 0; i < index; i++) {
            temp[i] = data[i];
        }
        data = temp;
    }

    public String pop() {
        if (isEmpty()) {
            return null;
        } else {
            String temp = data[--index];
            data[index] = null;
            return temp;
        }
    }

    public int getSize() {

        return index;
    }

    public boolean isEmpty() {
        return index == 0;
    }


}

package edu.quene;



/**
 * 数组实现循环队列
 *
 * 阻塞队列实现需要考虑的问题
 * 1,排队,偶空闲的时候再拿,
 * 2,丢弃,不处理,直接抛出
 * 3,队列一定要有边界,所以建议
 * @author: LHT
 * @date: 2020/12/13 13:53
 */
public class ArrayQueue {

    /**
     * 队头
     */
    private int head = 0;
    /**
     * 队尾
     */
    private int tail = 0;

    /**
     * 数据
     */
    private int[] data;
    /**
     * 队列的初始长度
     */
    private int caption;
    /**
     * 队列的大小
     */
    private int size;

    /**
     * 初始化队列
     *
     * @param size
     */
    public ArrayQueue(int size) {
        data = new int[size];
        this.size = 0;
        this.caption = size;

    }

    /**
     * 入队
     *
     * @param value
     */
    public void push(int value) {
        if (size == caption) {
            return;
        } else {

            data[tail] = value;
            tail++;
            tail = (tail + 1) % caption;
            size++;
        }
    }

    /**
     * 出队列
     *
     * @return
     */
    public int pop() {
        if (size == 0) {
            return -1;
        } else {
            int m = data[head];
            head++;
            head = (head + 1) % caption;
            size--;
            return m;
        }
    }

    public boolean isEmpty() {
        return tail == head;
    }

    public int getSize() {
        return this.size;
    }
}

package edu.list;

/**
 * @author: LHT
 * @date: 2020/12/12 16:48
 */
public class LinkList {
    ListNode head;
    int size;

    /**
     * 插入元素
     * 新建一个节点
     * 将新建的节点的下一个节点指向当前的节点头
     * 将最新的头指向新插入的节点
     */
    public void insertHead(Object value) {
        ListNode listNode = new ListNode(value);
        listNode.next = this.head;
        this.head = listNode;
    }

    /**
     * 插入元素
     * 新建一个节点
     * 将新建的节点的下一个节点指向当前的节点头
     * 将最新的头指向新插入的节点
     */
    public void insertPosition(Object value, int position) {
        if (position == 0) {
            //头部插入
            insertHead(value);
        } else {
            //遍历寻找,需要插入节点current
            ListNode current = head;
            for (int i = 1; i < position; i++) {
                current = current.next;
            }
            ListNode node = new ListNode(value);
            //iang新节点的下一个节点指向查找到节点的尾部。
            node.next = current.next;
            //将查找到的节点的下一个节点指向新节点
            current.next = node;
        }

    }

    /**
     * 删除
     */
    public void delete(int position) {
        if (position == 0) {
            //头部插入
            deleteHead();
        } else {
            //遍历寻找,需要删除节点current
            ListNode current = head;
            for (int i = 1; i < position; i++) {
                current = current.next;
            }
            current.next = current.next.next;
        }
    }

    /**
     * 删除头节点
     */
    public void deleteHead() {
        this.head = this.head.next;
    }

    /**
     * 查找
     */
    Object find(Object index) {
        ListNode cur = head;
        while (cur.next != null) {
            if (index.equals(cur)) {
                return cur;
            } else {
                cur = cur.next;
            }
        }
        return null;
    }
}

class ListNode {
    Object value;
    ListNode next;

    ListNode(Object value) {
        this.value = value;
    }
}


package time;

/**
 *  计算算法时间复杂度
 *  常数:O(1)
 *  对数:O(logn),O(nlogn)
 *  线性:O(n)
 *  线性对数:O(nlogn)
 *  平方:O(n^2)
 *  N次方:O(n^n)
 *  怎么找时间复杂度
 *  1,找到有循环的地方
 *  2,找有网络请求的(RPC,远程,分布式,数据库请求)的地方
 *  就是测试时间:log打印,计算平均时间
 *  学习算法的目地就是把代码写到最优。
 *  优化的目标就是O(n^n)=>O(nlogn)=>O(logn)==>o(1);
 *
 *  空间复杂度,就是找代码程序所占用JVM的空间
 *  INT []P,LIST MAP .......
 *
 *  学习思路
 *  (1)提升能力的:全部学
 *  (2)突击面试:注意几个景点:链表,排序算法,二叉树,红黑树,B-TREE B+TREE
 *  (3)树+图论+专项
 *
 */
public class BigO {

    public static void main(String[] args) {
       //常数级别:O{1}
        int a=1;    //运行1次  时间复杂度 O(1);
        //所有能确定的常熟都是O(1),O(10000)  ==>O(1)
        for (int i=0;i<3;i++){  //运行四次(0,1,2,3,4),多一次判断,第四次判断跳出 O(1);
            a=a+i;  //运行三次  O(1)
        }
        /**i的值  2 4 8 16   2^n
         * 即  2^x=n;  即  x=  log2(n);
         * 计算机忽略常熟   即  x=log(n);
         */
        int n=Integer.MAX_VALUE  //N是未知数
                ,i=0;
        while (i<=n){
            i=i*2;
        }

        /**i的值  3 9  27   3^n
         * 即  3^x=n;  即  x=  log3(n);
         * 计算机忽略常熟   即  x=log(n);
         */
        while (i<=n){
            i=i*3;
        }

        //n=nlogn
        for (int j=0;j<n;j++){
            while (i<=n){
                i=i*3;
            }
        }
        //二分查找算法复杂度为  x=logn= =>O(n^2)
        for (int j=0;j<n;j++){
           a=a+1;  //  ,如果n是未知数,   O(n)   or  已知数  O(N)
        }

        /**
         * 1,2,3,4,5,6,7 n  =n(n+1)/2==》 算法复杂度  o(n^2)
         */
        for (i=0;i<n;i++){
            for (int j=0;j<n;j++){
                a=a+1;  //  ,如果n是未知数,指数   O(n^2)   or  已知数  O(N^2)
            }
        }
    }

}