常见重要算法

重要算法

排序

package review.sort;

import java.util.Arrays;

/**
 * @Author: xiang
 * @Date: 2021/7/5 14:20
 */
public class BaseSort {

    public static void main(String[] args) {
        int[] array = {4,3,5,8,1,5,6,10,14,3,21,100};
        System.out.println(Arrays.toString(array));
        quickSort(array,0, array.length-1);
        System.out.println(Arrays.toString(array));
    }

    // 冒泡排序
    public static void bubbleSort(int[] array){
        if (array == null || array.length<2) return;
        boolean change = false;
        for (int i=array.length-1; i > 0;i--){
            for (int j=0;j<i;j++){
                if (array[j] > array[j+1]){
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                    change = true;
                }
            }
            if (!change) return;
        }
    }

    //插入排序
    public static void insertSort(int[] array){
        if (array == null || array.length<2) return;
        for (int i=0;i<array.length;i++){
            int value = array[i];
            int j=i-1;
            for (;j>-1;j--){
                if (array[j] > value)
                    array[j+1] = array[j];
                else
                    break;
            }
            array[j+1] = value;
        }
    }

    // 归并排序
    public static void mergeSort(int[] array,int begin,int end){
        if (begin >= end) return;
        int mid = (begin+end)/2;
        mergeSort(array,begin,mid);
        mergeSort(array,mid+1,end);
        merge(array,begin,mid,end);
    }

    private static void merge(int[] array, int begin, int mid, int end) {
        int[] tmp = new int[end-begin+1];
        int left = begin;
        int right = mid+1;
        int i=0;
        while (left < mid+1 && right<end+1){
            if (array[left] <= array[right])
                tmp[i++] = array[left++];
            else
                tmp[i++] = array[right++];
        }
        if (left == mid+1)
            System.arraycopy(array,right,tmp,i,end-right+1);
        else
            System.arraycopy(array,left,tmp,i,mid-left+1);
        System.arraycopy(tmp,0,array,begin,end-begin+1);
    }

    // 快速排序
    public static void quickSort(int[] array,int begin,int end){
        if (end - begin < 1) return;
        int i = partition(array,begin,end);
        quickSort(array,begin,i);
        quickSort(array,i+1,end);
    }

    private static int partition(int[] array,int begin,int end) {
        int i = begin;
        int j = begin;
        while (j<=end){
            // 分区点
            int value = array[end]; //选取最后一个元素作为分区点
            if (array[j] <= value){
                int tmp = array[i];
                array[i] = array[j];
                array[j] = tmp;
                i++;
            }
            j++;
        }
        return i==j ? i-2:i-1;
    }
}

归并算法时间复杂度计算分析

在这里插入图片描述

二分查找

package review.search;

import java.util.Arrays;

/**
 * @Author: xiang
 * @Date: 2021/7/5 17:03
 */
public class BinarySearch {
    public static void main(String[] args) {
        int[] array = {4,3,5,8,1,5,6,3,3,10,14,3,21,100};
        Arrays.sort(array);
        System.out.println(Arrays.toString(array));
        System.out.println(searchFist(array,3));
        System.out.println(searchLast(array,3));
        System.out.println(searchFirstLargest(array,3));
        System.out.println(searchLastLeast(array,3));
    }

    /**
     * 二分查找
     * 未查找到返回-1
     *
     * 注:求什么 就在该条件下 if ( (mid == ?) || a[mid +/- 1] ? dest)
     */
    // 查找元素第一个位置
    public static int searchFist(int[] a,int dest){
        int left = 0;
        int right = a.length-1;
        while (left<=right){
            int mid = (left+right)>>1;
            if (a[mid] < dest){
                left = mid+1;
            }else if (a[mid] > dest){
                right = mid-1;
            }else {
                if ((mid == 0) || a[mid-1] != dest)
                    return mid;
                else
                    right = mid-1;
            }
        }
        return -1;
    }

    // 查找元素最后一个位置
    public static int searchLast(int[] a,int dest){
        int left = 0;
        int right = a.length-1;
        while (left<=right){
            int mid = (left+right)>>1;
            if (a[mid] < dest){
                left = mid+1;
            }else if (a[mid] > dest){
                right = mid-1;
            }else {
                if ((mid == a.length-1) || (a[mid+1] != dest))
                    return mid;
                else
                    left = mid+1;
            }
        }
        return -1;
    }

    // 查找第一个大于等于给定值的元素
    public static int searchFirstLargest(int[] a, int dest){
        int left = 0;
        int right = a.length-1;
        while (left<=right){
            int mid = (left+right)>>1;
            if (a[mid] >= dest){
                if ( (mid == 0) || a[mid-1] < dest)
                    return mid;
                else
                    right = mid-1;
            }else {
                left = mid+1;
            }
        }
        return -1;
    }

    // 查找最后一个小于等于给定值的元素
    public static int searchLastLeast(int[] a, int dest){
        int left = 0;
        int right = a.length-1;
        while (left <= right){
            int mid = (left + right)>>1;
            if (a[mid] <= dest){
                if ((mid == a.length-1) || a[mid+1] > dest)
                    return mid;
                else
                    left = mid+1;
            }else {
                right = mid-1;
            }
        }
        return -1;
    }
}

非递归遍历二叉树

记住:

    for root != nil || len(stack) > 0 {
		for root != nil {
			......	
            stack = append(stack,root)
            root = root.Left
        }
        ......
   }

前序遍历

func preorderTraversal(root *TreeNode) []int {
    var res []int
    stack := []*TreeNode{}
    for root != nil || len(stack) > 0 {
        for root != nil {
            res = append(res,root.Val)
            stack = append(stack,root)
            root = root.Left
        }
        root = stack[len(stack)-1].Right
        stack = stack[:len(stack)-1]
    }
    return res
}

中序遍历

func inorderTraversal(root *TreeNode) []int {
    var res []int
    stack := []*TreeNode{}
	for root != nil || len(stack) > 0 {
		for root != nil {
			stack = append(stack, root)
			root = root.Left
		}
		root = stack[len(stack)-1].Right
		res = append(res, stack[len(stack)-1].Val)
        stack = stack[:len(stack)-1]
	}
	return res
}

后续遍历(多一个变量:上一个被记录的节点)

func postorderTraversal(root *TreeNode) []int {
    var res []int
    stack := []*TreeNode{}
    var pre *TreeNode //上一个被记录的元素
    for root != nil || len(stack) > 0 {
        for root != nil {
            stack = append(stack,root)
            root = root.Left
        }
        node := stack[len(stack)-1]
        if node.Right != nil && node.Right != pre {
            root = node.Right
        }else{
            res = append(res,node.Val)
            pre = node //该节点已被记录
            stack = stack[:len(stack)-1]
        }
    }
    return res
}
    // 层次遍历
    public static void levelOrder(TreeNode<Integer> root){
        if (root == null) return;
        Queue<TreeNode<Integer>> deque = new LinkedList<>();
        deque.add(root);
        while (!deque.isEmpty()){
            TreeNode<Integer> tmp = deque.poll();
            System.out.print(tmp.date + " ");
            if (tmp.left != null){
                deque.add(tmp.left);
            }
            if (tmp.right != null){
                deque.add(tmp.right);
            }
        }
    }
}

Graph图

package review.graph;

import java.util.ArrayList;

/**
 * @Author: xiang
 * @Date: 2021/7/6 10:24
 *
 * 邻接表实现图
 */
public class Graph {
    private ArrayList<ArrayList<Integer>> graph;
    private int size; //图中有多少种元素(节点数)
    private boolean direction; //是否为有向图

    // 构造图
    public Graph(int size,boolean direction) {
        graph = new ArrayList<>(size);
        for (int i=0;i<size;i++){
            graph.add(new ArrayList<>());
        }
        this.size = size;
        this.direction = direction;
    }

    // 获取邻接表中的一条数据
    public ArrayList<Integer> getAround(int n){
        return graph.get(n);
    }

    // 添加元素
    public void add(int start,int end){
        graph.get(start).add(end);
        if (!direction) graph.get(end).add(start);
        size++;
    }

    // 删除元素
    public void delete(int start,int end){
        graph.get(start).remove((Integer) end);
        if (!direction) graph.get(end).remove((Integer) start);
        size--;
    }

    // 图中元素个数
    public int getSize() {
        return size;
    }
}

在这里插入图片描述

package review.graph;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;

/**
 * @Author: xiang
 * @Date: 2021/7/6 10:43
 */
public class Traversal {

    public static void main(String[] args) {
        Graph graph = new Graph(6, false); //六个节点(从0~5的数字)
        graph.add(0,1);
        graph.add(0,2);
        graph.add(1,3);
        graph.add(1,2);
        graph.add(2,3);
        graph.add(2,4);
        graph.add(3,4);
        graph.add(3,5);
        BFS(graph,1);
        System.out.println();
        DFS(graph,1);
    }

    // 广度优先搜索   (1.遍历标识  2.队列)
    public static void BFS(Graph graph,int start){
        // 1.标志未访问
        boolean[] visited = new boolean[graph.getSize()];
        // 2.广度搜索 ==> 队列 (类似二叉树的按层遍历)
        Queue<Integer> queue = new LinkedList<>();
        // 注意:在放入队列中后 应立即修改为已遍历
        // 3.放入将查找的初始节点
        queue.add(start);
        visited[start] = true;
        while (!queue.isEmpty()){
            // 4.取出队首元素输出 并将其未遍历的邻接点加入队列中
            Integer v = queue.poll();
            System.out.print(v + " --> ");
            for (Integer n: graph.getAround(v)){
                if (!visited[n]){
                    queue.add(n);
                    visited[n] = true; //注意:加入队列就代表已遍历了!!!
                }
            }
        }
    }

    // 深度优先搜索  (1.遍历标识  2.栈)
    public static void DFS(Graph graph,int start){
        // 1.标志未访问
        boolean[] visited = new boolean[graph.getSize()];
        // 2.深度优先搜索 ==> 栈
        Deque<Integer> stack = new ArrayDeque<>();
        // 3.将查找的初始节点放入栈中 (同样 入栈立即为已遍历)
        stack.push(start);
        visited[start] = true;
        while (!stack.isEmpty()){
            // 4.取出栈顶元素输出 并将其未遍历的邻接点压入栈中
            Integer v = stack.pop();
            System.out.print(v + " ==> ");
            for (Integer n: graph.getAround(v)){
                if (!visited[n]){
                    stack.push(n);
                    visited[n] = true; //注意:压入栈就代表已遍历了!!!
                }
            }
        }
    }
}

Java杂记(忽略)

  1. 先过滤掉特殊值 ⭐
  2. 重要数据结构及常用方法 ⭐⭐⭐⭐⭐
     // 队列
     Queue<Integer> queue = new LinkedList<>();
     queue.add(1);
     queue.poll();
     queue.peek(); //返回队首元素但不弹出
     queue.contains(1); //注意!!!
     queue.size();
     queue.clear();
     queue.isEmpty();
     
     // 栈
     Deque<Integer> stack = new ArrayDeque<>();
     stack.push(1);
     stack.pop();
     stack.peek(); //返回队首元素但不弹出
     stack.contains(1); //注意!!!
     stack.size();
     stack.clear();
     stack.isEmpty();
     
     /**
     * 注意:堆不能存重复元素
     **/
     // 小顶堆 
     PriorityQueue<Integer> heap = new PriorityQueue<>();
     heap.add(1);
     heap.poll();
     heap.peek(); //返回队首元素但不弹出
     heap.contains(1); //注意!!!
     heap.size(); 
     heap.clear();
     heap.isEmpty();

	// 大顶堆
	PriorityQueue<Integer> heap = new PriorityQueue<>((x,y) -> y-x);
  1. int[] intArray = arrayList.stream().mapToInt(Integer::intValue).toArray();
  2. 数组copy只记这个就行了System.arraycopy(stones,0,stones,0,length);
  3. 没有汉字的字符串利用数组下标计数。
  4. int max = Integer.MIN_VALUE;
  5. 拷贝返回一个新数组:copyOfRange(T[] original, int from, int to) 【左闭右开】
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值