力扣脚手架 | 常用数据结构模板集合

这篇博客详细介绍了多种数据结构和排序算法,包括冒泡排序、快速排序、插入排序、归并排序等。此外,还涉及了图论中的深度优先搜索、广度优先搜索、最小生成树和最短路径。对于树结构,讲解了基本遍历和并查集。最后,文章讨论了动态规划、回溯、递归等算法思想及其应用。
摘要由CSDN通过智能技术生成

排序

冒泡排序

算法思想

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

程序流程

  1. 最外层循环代表趟数,由于最后一趟定位两个数的次序,所以对于n个元素的数组来说,只需要 n-1 趟
  2. 第二层循环代表比较数字数,对于n个元素,最初只需要比较 n-1 次
  3. 第二次循环从1开始,是后者与前者比较
public void bubbleSort(int[] nums) {
	for(int i = 0; i < nums.length - 1; i++) {
		for(int j = 1; j < nums.length - i; j++) {
			if(nums[j] < nums[j-1]) {
				int tmp = nums[j-1];
				nums[j-1] = nums[j];
				nums[j] = tmp;
			}
		}
	}
}

快速排序

算法思想

排序思想 快速排序是一种划分交换排序。它采用了一种分治的策略,通常称其为分治法。

  1. 先从数列中取出一个数作为基准数。
  2. 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
  3. 再对左右区间重复第二步,直到各区间只有一个数。

程序流程

类似树的先序遍历

private void quicksort(int[] nums, int start, int end)
{
    if(start >= end)
        return;
    int mid = start + (end - start) / 2;
    int midval = nums[mid];
    int p = start, q = end;
    while(p <= q)
    {
        while(p <= q && nums[p] < midval)
            ++p;
        while(p <= q && nums[q] > midval)
            --q;
        if(p <= q)
        {
            swap(nums[p], nums[q]);
            ++p;
            --q;
        }
    }
    quicksort(nums, start, q);
    quicksort(nums, p, end);
}


插入排序

算法思想

  1. 对于一个数组 A[0,n] 的排序问题,假设认为数组在 A[0,n-1] 排序的问题已经解决了。
  2. 考虑 A[n]的值,从右向左扫描有序数组 A[0,n-1] ,直到第一个小于等于 A[n] 的元素,将 A[n] 插在这个元素的后面。

程序流程

private void insertSortion(int[] nums) {
	if(nums.size() < 2) return;
	for(int i = 1; i < nums.size(); i++) {
		int num = nums[i];
		// 防止插入的数是最小的 
		bool flag = false;
		// for循环中,若插入值是最小的,没有给最小的值安排位置 
		for(int j = i - 1; j > -1; j--) {
			if(nums[j] > num) {
				nums[j+1] = nums[j];
			} else {
				nums[j+1] = num;
				flag = true;
				break;
			}
		}
		if(!flag) {
			nums[0] = num; 
		}
	}
	return;
} 

拓扑排序

算法思想

  1. 从有向图中选一个无前驱(入度为0)的顶点输出
  2. 将此顶点和以它为起点的弧删除
  3. 重复步骤1和步骤2,直到不存在无前驱的顶点
  4. 若此时输出的顶点数小于有向图中的顶点数,则说明有向图中存在回路
  5. 否则输出的顶点的顺序即为一个拓扑序列。

程序流程

  1. 建立入度表
  2. 创建图谱(也就是连接关系) Map<Integer, Set>,需要注意第一个建立得到的set为null,所以要判断是否为null,为null则要新建一个,不为null就添加
  3. 找入度为0的数入队列
  4. 如果队列容量大于1,则拓扑序列不唯一
  5. 不断遍历查询节点,把与当前节点相连的节点的入度减1,并把入度为0的结点放入数组
public boolean sequenceReconstruction(int[] nums, int[][] sequences) {
    // 1.建立图谱
    // 构建入度表
    int[] inDegree = new int[nums.length+1];
    // 创建连接关系
    Map<Integer, Set<Integer>> map = new HashMap<>();
    for(int[] sequence: sequences) {
        for (int i = 0; i < sequence.length-1; i++) {
            int key = sequence[i];
            Set<Integer> set = map.get(key);
            if (set==null){
                set = new HashSet<>();
                map.put(key, set);
            }
            if(!set.contains(sequence[i+1])) {
                inDegree[sequence[i+1]]++;
            }
            set.add(sequence[i+1]);

        }
    }
    // 2.查入度为0的数,如果入度为0,进入队列
    Queue<Integer> queue = new LinkedList<>();
    for (int i = 1; i < inDegree.length; i++) {
        if (inDegree[i]==0){
            queue.add(i);
        }
    }
    // 3.如果队列容量大于1,返回false
    if (queue.size()>1) {
        return false;
    }
    // 4。遍历下一个节点
    while(!queue.isEmpty()) {
        // 获得key
        int front = queue.poll();
        // 遍历下一个节点
        Set<Integer> set = map.get(front);
        if (set==null) break;
        // 遍历节点,把入度为0的结点放入数组
        for (Integer val : set) {
            inDegree[val]--;
            if (inDegree[val]==0) {
                queue.add(val);
            }
        }
        if (queue.size()>1) {
            return false;
        }
    }
    for (int i = 1; i < inDegree.length; i++) {
        if (inDegree[i]!=0) {
            return false;
        }
    }
    return true;
}

归并排序

图论

深度优先搜索

广度优先搜索/层序遍历

public void findByBFS(TreeNode root) {
	if(root==null) return;
   Queue<TreeNode> queue = new LinkedList<>();
   queue.add(root);
   while(!queue.isEmpty()) {
       int queueSize = queue.size();
       while(queueSize-- > 0) {
           // 得到树的根
           TreeNode node = queue.poll();
           if (node.left!=null)
               queue.add(node.left);
           if (node.right!=null)
               queue.add(node.right);
           System.out.print(node.val);
       }
   }
}

最小生成树

最短路径

树的基本遍历

并查集

其他算法及算法思想

动态规划

回溯

递归

备忘录

链表类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_之桐_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值