IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> TwoSugar的算法笔记 -> 正文阅读

[数据结构与算法]TwoSugar的算法笔记

TwoSugar的算法笔记

时间、空间复杂度

时间复杂度

  • 时间复杂度是用来估计算法运行时间的一个式子(单位)
  • 一般来说,时间复杂度高的算法比时间复杂度低的算法慢
  • 常见的时间复杂度(按效率排序):O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n2logn)<O(n^3)
  • 复杂问题的时间复杂度:O(n!)、O(2n)、O(nn)

快速判断时间复杂度的方法(简单情况)

  • 确定问题规模n(例如:循环次数)
  • 循环过程减半(logn)
  • k层关于n的循环(n^k)

复杂情况:根据算法执行过程进行判断

空间复杂度

  • 空间复杂度:用来评估算法内存占用大小的式子
  • 空间复杂度的表示方式与时间复杂度完全一样
    • 算法使用了几个变量(O(1))
    • 算法使用了几个长度为n的一维数组(O(n))
    • 算法使用了几个m行n列的二维数组(O(mn))
  • 空间换时间

递归

递归的两个特点

  • 调用自身
  • 结束条件

查找

在一些元素中通过一定的方法找到与给定关键字相同的数据元素的过程

列表查找:

  1. 顺序查找
  2. 二分查找

python内置函数index()

排序

排序总览

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3YmpHV63-1637246864044)(D:\桌面\笔记\排序.jpg)]

冒泡排序、选择排序、插入排序

使用场景:

//这都不会,重开吧。

快速排序

快排的过程可以看作递归+划分

注:为方便记忆算法,我习惯将其记作“递归+划分” ------sort(partition,sort,sort) + partition(while{while,while})

使用场景:

    public void quickSort(int[] nums){
        sort(nums, 0, nums.length-1);
    }
	//递归
    public void sort(int[] nums, int i, int j){
        if( i >= j )return;//递归结束条件
        int p = partition(nums, i, j);
        sort(nums, i, p-1);
        sort(nums, p+1, j);
    }
	//划分
    public int partition(int[] nums, int i, int j){
        int p = nums[i];
        while( i < j ){
            while( i < j && nums[j] >= p ){
                j--;//从右往左找到第一个<p的
            }
            nums[i] = nums[j];
            while( i < j && nums[i] <= p ){
                i++;//从左往右找到第一个>p的
            }
            nums[j] = nums[i];
        }
        nums[i] = p;//最后把p放到对应位置
        return i;
    }

可以使用快排解决的问题:

堆排序

堆排序的过程可以拆解为

  • 生成大根堆
  • 不断将根顶取下并进行调整从而排序
  • 调整函数

注:为方便记忆算法,我习惯将其记作“生成大根堆+调整+排序” ------for(第一个非叶子节点){adjust()}+for(第一个叶子节点){swap(堆顶,叶子节点),adjust}+adjust(){for(){if+if}}

使用场景:

    public void sort(int[] nums){
        //生成大根堆
        for(int i=(nums.length-1)/2;i>=0;i--){
            adjustHeap(nums,i,nums.length);
        }
        //不断将根顶取下并进行调整从而排序
        for(int j=nums.length-1;j>0;j--){
            swap(nums,0,j);
            adjustHeap(nums,0,j);
        }
    }
    public void adjustHeap(int[] nums,int i,int length){
        int tmp=nums[i];
        for(int k=i*2+1;k<length;k=k*2+1){
            if(k+1<length&&nums[k]<nums[k+1]){
                k++;
            }
            if(nums[k]>tmp){
                nums[i]=nums[k];
                i=k;
            }else{
                break;
            }
        }
        nums[i]=tmp;
    }

    public void swap(int[] nums,int a,int b){
        int tmp=nums[a];
        nums[a]=nums[b];
        nums[b]=tmp;
    }

可以使用堆排序解决的题:

topk问题

topk问题:从arr[1, n]这n个数中,找出最大的k个数,这就是经典的TopK问题

实现方法:

  1. 冒泡排序(排k趟)O(mn)
  2. 排序后进行切片,O(nlogn)+k
  3. 堆排序O(nlogk)
    1. 构建小根堆
    2. 新加入元素与根顶进行比较
    3. 调用调整函数

归并排序

归并排序的过程可以看作是先分解再聚合,通过将待排序目标进行分解从而达到方便排序的目标,最后通过合并函数将已经排序的两个序列进行合并

注:为方便记忆算法,我习惯将其记作“递归+合并” ------sort(sort,sort,merge)merge(while,while,while,while)

使用场景:

import java.util.Arrays;

public class MergeSort {
    public static void main(String []args){
        int []arr = {9,8,7,6,5,4,3,2,1};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static void sort(int []arr){
        int []temp = new int[arr.length];//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
        sort(arr,0,arr.length-1,temp);
    }
    private static void sort(int[] arr,int left,int right,int []temp){
        if(left<right){
            int mid = (left+right)/2;
            sort(arr,left,mid,temp);//左边归并排序,使得左子序列有序
            sort(arr,mid+1,right,temp);//右边归并排序,使得右子序列有序
            merge(arr,left,mid,right,temp);//将两个有序子数组合并操作
        }
    }
    private static void merge(int[] arr,int left,int mid,int right,int[] temp){
        int i = left;//左序列指针
        int j = mid+1;//右序列指针
        int t = 0;//临时数组指针
        while (i<=mid && j<=right){
            if(arr[i]<=arr[j]){
                temp[t++] = arr[i++];
            }else {
                temp[t++] = arr[j++];
            }
        }
        while(i<=mid){//将左边剩余元素填充进temp中
            temp[t++] = arr[i++];
        }
        while(j<=right){//将右序列剩余元素填充进temp中
            temp[t++] = arr[j++];
        }
        t = 0;
        //将temp中的元素全部拷贝到原数组中
        while(left <= right){
            arr[left++] = temp[t++];
        }
    }
}

可以使用归并排序解决的问题:

希尔排序

希尔排序(Shell Sort)插入排序的一种算法,是对直接插入排序的一个优化,也称缩小增量排序

  • 希尔排序是非稳定排序算法。
  • 希尔排序因DL.Shell于1959年提出而得名。

注:为方便记忆算法,我习惯将其记作“三层for循环+if” ------** for(for(for(if)))**)

使用场景:


可以使用希尔排序解决的问题:

计数排序

使用场景:


可以使用计数排序解决的问题:

基数排序

使用场景:


可以使用基数排序解决的问题:

桶排序

使用场景:


可以使用捅排序解决的问题:

便记忆算法,我习惯将其记作**“三层for循环+if”** ------** for(for(for(if)))**)

使用场景:


可以使用希尔排序解决的问题:

计数排序

使用场景:


可以使用计数排序解决的问题:

基数排序

使用场景:


可以使用基数排序解决的问题:

桶排序

使用场景:


可以使用捅排序解决的问题:

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-19 17:52:03  更:2021-11-19 17:54:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 1:37:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码