手写一些常见算法

快速排序

public class Main {
    public static void main(String[] args) {
        int nums[] = {1,3,2,5,4,6,8,7,9};
        quickSort(nums,0,nums.length - 1);
    }
    private static void quickSort(int[] nums, int left, int right) {
        if(left >= right)
            return;
        // 划分数组 得到以privot为中心的数组 左小于privot 右大于privot
        int privot = partition(nums, left, right);
        // 递归左边和右边
        quickSort(nums, left, privot - 1);
        quickSort(nums,privot + 1, right);
    }

    private static int partition(int[] nums, int left, int right) {
        // 选基准
        int p = nums[right];
        // 指向大于等于基准元素的前一个位置
        int l = left - 1;
        for(int r = 0; r < right; r++){
            if(nums[r] < p){
                l++;
                int tmp = nums[r];
                nums[r] = nums[l];
                nums[l] = tmp;
            }
        }
        // 再对基准元素放置l+1处,因为l是指向前一个大于等于基准的位置
        nums[right] = nums[l + 1];
        nums[l + 1] = p;
        return l + 1;
    }
}

归并排序

public class QuickAndMerge {
    static int res = 0;
    public static void main(String[] args) {
        int nums[] = {1,3,2,5,4,6,8,7,9};
        int res[] = mergeSort(nums, 0, nums.length - 1);
    }
    private static int[] mergeSort(int nums[], int left, int right){
    	// 当排序长度为1,直接返回对应元素
        if(left == right)
            return new int[]{nums[left]};
        // 划分
        int mid = (right - left)/2 + left;
        int l[] = mergeSort(nums, left, mid);
        int r[] = mergeSort(nums, mid + 1, right);
        return mergeTwoArray(l,r);
    }
    private static int[] mergeTwoArray(int l[], int r[]){
        int res[] = new int[l.length + r.length];
        int num = 0;
        int l_num = 0;
        int r_num = 0;
        // 依次选取两数组中较小的元素
        while(l_num < l.length && r_num < r.length){
            res[num++] = l[l_num] < r[r_num] ? l[l_num++]:r[r_num++];
        }
        // 处理剩余元素
        while(l_num < l.length){
            res[num++] = l[l_num++];
        }
        while(r_num < r.length){
            res[num++] = r[r_num++];
        }
        return res;
    }

Dijkstra

public class Main{
    public static void main(String[] args) {
        int n = Integer.MAX_VALUE/2;
        int node[] = {1,2,3,4,5};
        int matrix[][] = new int[node.length + 1][node.length + 1];
        matrix[1] = new int[]{n, 0, 1, n, 3, n};
        matrix[2] = new int[]{n, n, 0, 3, 1, n};
        matrix[3] = new int[]{n, n, n, 0, n, 1};
        matrix[4] = new int[]{n, n, n, 1, 0, n};
        matrix[5] = new int[]{n, n, n, n, n, 0};
        // 求1到其它点的最短距离
        int distance[] = {n, 0, n, n, n, n};
        // 每次从一点开始搜索
        boolean accessed[] = new boolean[node.length + 1];
        // 共node.length个点
        for(int i = 0; i < node.length; i++){
            int curIndex = findMin(distance, accessed);
            accessed[curIndex] = true;
            // 如果有更短路径则更新
            for(int j = 1; j < distance.length; j++){
                if(curIndex != j && distance[j] > matrix[curIndex][j] + distance[curIndex]){
                    distance[j] = matrix[curIndex][j] + distance[curIndex];
                }
            }
        }
        System.out.println(distance[5]);
    }
    // 找最小distance的一个,易得起始节点到此点的距离已最小,可以开始对其邻居进行访问
    private static int findMin(int[] distance, boolean[] accessed) {
        int index = 1;
        int min = Integer.MAX_VALUE;
        for(int i = 1; i < distance.length; i++){
        if(!accessed[i] && min > distance[i]){
            min = distance[i];
            index = i;
        }
        }
        return index;
    }
}

自定义排序

import java.util.Arrays;
import java.util.Comparator;
public class Student{
    int score;
    int age;
    Student(int score, int age){
        this.score = score;
        this.age = age;
    }
    public int getScore() {return score;}
    public void setNum(int score) {
        this.score = score;
    }
    public int getAge() {return age;}
    public void setAge(int age) {
        this.age = age;
    }
    public static void main(String[] args) {
            Student stu[] = new Student[3];
            stu[0] = new Student(1,2);
            stu[1] = new Student(1,0);
            stu[2] = new Student(2,0);
            // 写法1 匿名内部类
            Arrays.sort(stu, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                if(o1.getScore() != o2.getScore())
                    return o2.getScore() - o1.getScore();
                return o1.getAge() - o2.getAge();
            }
            });
            
            // 写法2 lambda
            Arrays.sort(stu, ((o1, o2) -> {
                if(o1.getScore() != o2.getScore())
                    return o2.getScore() - o1.getScore();
                return o1.getAge() - o2.getAge();
            }));
            
            // 写法3
            Arrays.sort(stu, Comparator.comparing(Student::getScore)
                .reversed()
                .thenComparing(Student::getAge));
    }
}

交替打印偶数奇数200个

public class Main{
    private static final Object lock = new Object();
    private static int count = 0;
    private static final int MAX = 200;
    public static void main(String[] args) {
        // 创建线程 将实现了Runnable接口的printer放入,start启动
        Thread thread1 = new Thread(new Printer(), "线程1");
        Thread thread2 = new Thread(new Printer(), "线程2");
        thread1.start();
        thread2.start();
    }
    static class Printer implements Runnable {
        // 重写Run方法
        @Override
        public void run() {
            while (true) {
                // synchronized
                synchronized (lock) {
                    // 打印完成
                    if (count > MAX) {
                        break;
                    }
                    System.out.println(Thread.currentThread().getName() + "打印数字: " + count++);
                    // 唤醒等待锁的线程
                    lock.notify();
                    try {
                        if (count <= MAX) {
                            lock.wait();
                        }
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }
    }
}

冒泡排序

public class BubbleSort {
    public static void main(String[] args) {
        int bubble[] = {8,7,6,5,4,3,2,1};
        //bubbleSort(bubble);
        bubbleSortDesc(bubble);
    }
    private static void bubbleSort(int[] bubble) {
        for(int i = 0; i < bubble.length; i++){
            int flag = 0;
            for(int j = 0; j < bubble.length - i - 1; j++){
                if(bubble[j] < bubble[j + 1]){
                    swap(bubble, j, j + 1);
                    flag = 1;
                }
            }
            if(flag == 0)
                break;
        }
    }
    private static void bubbleSortDesc(int[] bubble) {
        for(int i = 0; i < bubble.length; i++){
            int flag = 0;
            for(int j = 0; j < bubble.length - i - 1; j++){
                if(bubble[j] > bubble[j + 1]){
                    swap(bubble, j, j + 1);
                    flag = 1;
                }
            }
            if(flag == 0)
                break;
        }
    }
    private static void swap(int bubble[], int i, int j){
        int temp = bubble[i];
        bubble[i] = bubble[j];
        bubble[j] = temp;
    }
}

插入排序

public class InsertSort {
    public static void main(String[] args) {
        int insert[] = {1,4,2,6,3,5,8,7};
        insertSort(insert);
    }
    private static void insertSort(int[] insert) {
        for(int i = 1; i < insert.length; i++){
            int i2 = i;
            int temp = insert[i2];
            while (i2 > 0 && temp < insert[i2 - 1]){
                insert[i2] = insert[i2 - 1];
                i2--;
            }
            insert[i2] = temp;
        }
    }
}

堆排序

public class HeapSort {
    public static void main(String[] args) {
        int nums[] = {1,3,4,2,6,5};
        heapSort(nums);
    }
    public static void heapSort(int[] nums) {
        int n = nums.length;
        // 挑整数组位置,使得父节点大于子节点,从最后一个非叶子节点开始
        for (int i = n / 2 - 1; i >= 0; i--) {
            adjust(nums, n, i);
        }
        // 依次从堆中提取元素,
        for (int i = n - 1; i > 0; i--) {
            // 将当前父节点移动到末尾
            int tmp = nums[0];
            nums[0] = nums[i];
            nums[i] = tmp;
            // 移动到末尾后继续调整堆
            adjust(nums, i, 0);
        }
    }
    private static void adjust(int[] nums, int n, int i) {
         // i表示父节点
        int largest = i;
        int left = 2 * i + 1; // 左子节点
        int right = 2 * i + 2; // 右子节点
        // 如果左子节点大于根节点
        if (left < n && nums[left] > nums[largest]) {
            largest = left;
        }
        // 如果右子节点大于当前最大值
        if (right < n && nums[right] > nums[largest]) {
            largest = right;
        }
        // 如果最大值不是根节点 交换节点位置,使得较大一方到父节点位置
        if (largest != i) {
            int tmp = nums[i];
            nums[i] = nums[largest];
            nums[largest] = tmp;
            // 调整交换后子节点所在的子树
            adjust(nums, n, largest);
        }
    }
}

欧几里得算法求最大公约数

public class Main6 {
        public static void main(String[] args) {
//            int a = 60;
//            int b = 24;
            int a = 24;
            int b = 60;
            System.out.println(gcd(a, b));
        }

        // 欧几里得算法
        public static int gcd(int a, int b) {
            while (b != 0) {
                int temp = b;
                b = a % b;
                a = temp;
            }
            return a;
        }
}

单例模式的双重校验

实例为空才进入同步块,较少锁开销

public class Singleton {
    // volatile修饰防止指令重排序
    private volatile static Singleton singletonInstance;

    // 私有构造方法防new
    private Singleton(){}

    // 对外获取实例
    public static Singleton getSingletonInstance(){
        // 双重判断 判断为空再加锁
        if(singletonInstance == null){
            synchronized (Singleton.class){
                if(singletonInstance == null){
                    singletonInstance = new Singleton();
                }
            }
        }
        return singletonInstance;
    }
}

LRU缓存

import java.util.HashMap;
import java.util.Map;

public class LRUCache {
    // 容量
    int capacity;
    Map<Integer, Node> map = new HashMap<>();
    Node dummy = new Node(0,0);
    class Node{
        int key,value;
        Node prev,next;
        Node(int key,int value){
            this.key = key;
            this.value = value;
        }
    }
    LRUCache(int capacity){
        this.capacity = capacity;
        dummy.next = dummy;
        dummy.prev = dummy;
    }
    int get(int key){
        // 查询且更新
        Node node = getNode(key);
        return node == null?-1:node.value;
    }
    void put(int key,int value){
        Node node = getNode(key);
        // 已存在 更新键值
        if(node != null){
            node.value = value;
            return;
        }
        // 创建新的节点
        node = new Node(key,value);
        pushFront(node);
        map.put(key, node);
        if(map.size() > capacity){
            Node out = dummy.prev;
            map.remove(out.key);
            remove(out);
        }
    }
    private Node getNode(int key) {
        // 键不存在
        if(!map.containsKey(key))
            return null;
        // 键存在需要移动
        Node node = map.get(key);
        remove(node);
        pushFront(node);
        return node;
    }
    private void pushFront(Node node) {
        node.prev = dummy;
        node.next = dummy.next;
        node.next.prev = node;
        node.prev.next = node;
    }
    private void remove(Node node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }
}

死锁

public class Main {
    static final Object A = new Object();
    static final Object B = new Object();
    public static void main(String[] args) {
        Thread t1 = new Thread(new runapp(), "Thread1");
        Thread t2 = new Thread(new runapp(), "Thread2");
        t1.start();
        t2.start();
    }
    static class runapp implements Runnable{
        @Override
        public void run() {
            if(Thread.currentThread().getName().equals("Thread1")){
                synchronized (A){
                    System.out.println("Thread1拿到了A");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    synchronized (B){
                        System.out.println("Thread1拿到了B");
                    }
                }
            }else{
                synchronized (B){
                    System.out.println("Thread2拿到了B");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    synchronized (A){
                        System.out.println("Thread2拿到了A");
                    }
                }
            }
        }
    }
}

生产者与消费者

import java.util.ArrayDeque;
import java.util.Queue;

public class ModelConAndProd {
    // 生产者消费者模型(线程):
    // 假设有多个消费者和多个生产者, 当队列有位置生产者才可以生产, 有物品消费者才可以消费
    static int capacity = 20;
    static Queue<Integer> queue = new ArrayDeque<>(capacity);
    static int number = 1;

    static class Productor implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (queue) {
                    if (queue.size() == capacity) {
                        try {
                            queue.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    } else {
                        System.out.println(Thread.currentThread().getName() + "生产了物品:" + number);
                        queue.add(number++);
                        queue.notifyAll();
                    }
                }
                // 生产完休息一下
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                }
            }
        }

    static class Consumer implements Runnable{
        @Override
        public void run() {
            while (true) {
                synchronized (queue) {
                    if (queue.size() == 0) {
                        try {
                            queue.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    } else {
                        int cur = queue.poll();
                        System.out.println(Thread.currentThread().getName() + "消费了物品" + cur);
                        queue.notifyAll();
                    }
                }
                // 消费完休息一下
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    public static void main(String[] args) {
        Thread[] p1 = new Thread[5];
        Thread[] c1 = new Thread[5];
        for(int i = 0; i < p1.length; i++){
             p1[i] = new Thread(new Productor(), "生产者" + (i + 1) + "号");
             p1[i].start();
        }

        for (int i = 0; i < c1.length; i++) {
            c1[i] = new Thread(new Consumer(), "消费者" + (i + 1) + "号");
            c1[i].start();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值