学习笔记【数据结构与算法-第一节:排序】

概述

什么是数据结构?

数据结构就是把数据元素按照一定的关系组织起来的集合,用来组织和存储数据

数据结构的分类:

逻辑结构:

  • 集合结构
  • 线性结构
  • 树形结构
  • 图形结构

物理结构:

  • 顺序结构
  • 链式结构
什么是算法?

根据一定的条件,对一些数据进行计算,得到需要的结果

优秀算法的目标
  • 1.花最少的时间完成需求
  • 2.占用最少的内存空间完成需求

算法分析

算法的时间复杂度分析

事后分析估算方法:如写计算时间的代码

事后分析估算方法:
因素:

  • 算法采用的策略和方案
  • 编译产生的代码质量
  • 问题的输入规模(所谓的问题输入规模就是输入量的多少)
  • 机器执行指令的速度

最重要的是把核心操作的次数和输入规模关联起来

  • 算法函数中的常数可以忽略不计
  • 算法函数中最高次幂的常数因子可以忽略
  • 算法函数中最高次幂越小,算法效率越高
算法时间复杂度

大O记法

  • 用常数1取代运行时间中的所有加法常数
  • 在修改后的运算次数中,只保留高阶项
  • 如果最高阶项存在,且常数因子不为1,则去除这个项相乘的常数

如:

  • 算法一:3次:O(1)
  • 算法二:n+3:O(n)
  • 算法三:n^2+2次: O(n^2)

常见的大O阶

  • 线性阶(如循环)
  • 平方阶(如嵌套循环)
  • 立方阶(如三层嵌套循环)
  • 常数阶
  • 对数阶

O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)

算法的空间复杂度分析(略)

以占用内存为标准,这里省略


排序

冒泡排序
 public static void sort01(int[] arr){
    for (int i=0;i<arr.length-1;i++){
        for (int j=0;j<arr.length-i-1;j++){
            if (arr[j]>arr[j+1]){
                int temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
    }
    print(arr);
}

时间复杂度:O(n^2)

选择排序
public static void sort02(int[] arr){
    for (int i=0;i<arr.length-1;i++){
        int min=i;
        for (int j=i+1;j<arr.length;j++){
            if (arr[min]>arr[j]){
                min=j;
            }
        }
        if (min!=i){
            int temp=arr[i];
            arr[i]=arr[min];
            arr[min]=temp;
        }
    }
    print(arr);
}

时间复杂度:O(n^2)

插入排序
public static void sort03(int[] arr){
    for (int i=1;i<arr.length;i++){
        for (int j=i;j>0;j--){
            if (arr[j-1]>arr[j]){
                int temp=arr[j];
                arr[j]=arr[j-1];
                arr[j-1]=temp;
            }else {
                break;
            }
        }
    }
    print(arr);
}

时间复杂度:O(n^2)

希尔排序
public static void sort04(int[] arr){
    int h=1;
    while (h<arr.length/2){
        h=h*2+1;
    }
    while(h>=1){
        for(int i=h;i<arr.length;i++){
            for (int j=i;j>=h;j-=h){
                if (arr[j-h]>arr[j]){
                    int temp=arr[j];
                    arr[j]=arr[j-h];
                    arr[j-h]=temp;
                }else {
                    break;
                }
            }
        }
        h=h/2;
    }
    print(arr);
}
归并排序
public class test {
    public static void sort(int[] arr){
        int l=0;
        int r=arr.length-1;
        mergeSort(arr,l,r);
        for (int i=0;i<arr.length;i++){
            System.out.print(arr[i]+"\t");
        }
    }


    private static void mergeSort(int[] arr,int l,int r){
        if (l>=r){
            return;
        }

        int mid=(l+r)>>>1;
        mergeSort(arr,l,mid);
        mergeSort(arr,mid+1,r);
        merge(arr,l,mid,r);
    }

    private static void merge(int[] arr,int l,int mid,int r){
        int s1=l;
        int s2=mid+1;

        int[] tempArr=new int[r-l+1];
        int i=0;

        while (s1<=mid&&s2<=r){
            if (arr[s1]<=arr[s2]){
                tempArr[i++]=arr[s1++];
            }else {
                tempArr[i++]=arr[s2++];
            }
        }

        while (s1<=mid){
            tempArr[i++]=arr[s1++];
        }
        while (s2<=r){
            tempArr[i++]=arr[s2++];
        }

        for (int j=0;j<tempArr.length;j++){
            arr[l+j]=tempArr[j];
        }
    }
}

时间复杂度:O(nlogn)

快速排序
public class Quick02 {
    public static void sort(int[] arr){
        int left=0;
        int right=arr.length-1;
        partitionSort(arr,left,right);

        for (int i=0;i<arr.length;i++){
            System.out.print(arr[i]+"\t");
        }
    }

    private static void partitionSort(int[] arr,int left,int right){
        if (right<=left){
            return;
        }

        int partition=partition(arr,left,right);

        partitionSort(arr,left,partition-1);
        partitionSort(arr,partition+1,right);
    }

    private static int partition(int[] arr,int left,int right){
        int s1=left;
        int s2=right+1;

        while (true){
            while (arr[left]<arr[--s2]){
                if (s2<=left){
                    break;
                }
            }
            while (arr[left]>arr[++s1]){
                if (s1>=right){
                    break;
                }
            }
            if (s1>=s2){
                break;
            }else {
                int temp=arr[s1];
                arr[s1]=arr[s2];
                arr[s2]=temp;
            }
        }

        int temp=arr[s2];
        arr[s2]=arr[left];
        arr[left]=temp;

        return s2;
    }
}

时间复杂度:
最优:O(nlogn)
最差:O(n^2)
平均:O(nlogn)

排序的稳定性:

数组arr中由若干个元素,其中A元素和B元素相等且在它前面,如果使用了某种排序算法后,A元素仍然在B元素前面,则说该算法是稳定的

常见算法的稳定性:

  • 冒泡排序 :稳定的
  • 选择排序 :不稳定的
  • 插入排序 :稳定的
  • 希尔排序 :不稳定的
  • 归并排序 :稳定的
  • 快速排序 :不稳定的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值