• 12.1排序


    目录

    0.修改栈堆内存

    一.堆排序

    1 原理

    2.代码实现

    3.分析

    二.冒泡排序

    1 原理

    2.实现

    3.分析

    三.快速排序(重要)

    1 原理-总览

    2.方法:挖坑法

    步骤一

    步骤二

    步骤三

    步骤四

    步骤五

    步骤六

    3.代码实现挖坑法

    4.分析

    四.字符串转整数

    1.字符串方法

    2.字符数组方法

    3.sb方法

    五.笔试强训


    0.修改栈堆内存

    一.堆排序

    1 原理

    基本原理也是选择排序,只是不在使用遍历的方式查找无序区间的最大的数,而是通过堆来选择无序区间的最大的数。

    注意: 排升序要建大堆;排降序要建小堆

    2.代码实现

    1. /**
    2. * 堆排序
    3. */
    4. public static void heapSort(int[] array){
    5. createHeap(array);
    6. int end=array.length-1;
    7. while(end>0){//等于0的时候就不需要调整了
    8. swap(array[0],array[end]);
    9. shiftDown(array,0,end);
    10. end--;
    11. }
    12. }
    13. public static void createHeap(int[] array) {
    14. for (int parent =(array.length-1-1)/2; parent >=0 ; parent--) {
    15. shiftDown(array,parent,array.length);
    16. }
    17. }
    18. public static void shiftDown(int[] array,int parent,int len){
    19. int child=parent*2+1;
    20. while(child
    21. if(child+11]){
    22. child++;
    23. }
    24. if(array[child]>array[parent]){
    25. swap(array[child],array[parent]);
    26. parent=child;
    27. child=parent*2+1;
    28. }else{
    29. break;
    30. }
    31. }
    32. }

    3.分析

    1. /**
    2. * 堆排序
    3. */
    4. /**
    5. * 时间复杂度:O(N * log N)
    6. *
    7. * 空间复杂度:O(1)
    8. *
    9. * 稳定性:不稳定
    10. *
    11. * 面试 写堆排序 就是 写的调整过程
    12. *
    13. * @param array
    14. */

    因为要遍历每个元素所以就是n然后最坏情况下要从上往下一直调整就是树的高度logn

    所以就是 时间复杂度:O(N * log N)

    二.冒泡排序

    1 原理

    在无序区间,通过相邻数的比较,将最大的数冒泡到无序区间的最后,持续这个过程,直到数组整体有序

    2.实现

    1. /**
    2. * 冒泡排序
    3. */
    4. public static void bubbleSort(int[] array) {
    5. for (int i = 0; i < array.length; i++) {
    6. //int max=i;
    7. int j = i+1;
    8. boolean flg=true;
    9. for (; j < array.length-i-1; j++) {
    10. if(array[j]>array[j+1]){
    11. swap(array[j],array[j+1]);
    12. flg=false;
    13. }
    14. }
    15. if(flg) return;
    16. }
    17. }

    3.分析

    1. /**
    2. * 冒泡排序
    3. * 时间复杂度:O(N^2)
    4. * 有序情况下:O(n)
    5. * 空间复杂度:O(1)
    6. * 稳定性:稳定的排序
    7. * @param array
    8. */

    三.快速排序(重要)

    1 原理-总览

    1. 从待排序区间选择一个数,作为基准值(pivot);
    2. Partition: 遍历整个待排序区间,将比基准值小的(可以包含相等的)放到基准值的左边,将比基准值大的(可

    以包含相等的)放到基准值的右边;

    3. 采用分治思想,对左右两个小区间按照同样的方式处理,直到小区间的长度 == 1,代表已经有序,或者小区间

    的长度 == 0,代表没有数据。

    2.方法:挖坑法

    步骤一

    先定义数组第一个元素tmp.挖坑

    步骤二

    再定义两个指针一个是end另外一个是start

    步骤三

    遍历end 如果比tmp大的end就往右移 也就是end--

    遇到比tmp小的就放到坑里

    停止遍历

    步骤四

    遍历start,遇到比tmp小的就左移,也就是start++

    遇到比tmp大的就放在end所在坑里

    停止遍历

    步骤五

    直到start与end相遇那么这个位置放入tmp的值,

    这个位置也是基准

    这样就发现基准的左边就比他小.基准的右边就比他大

    步骤六

    分而治之,再次递归.分别对基准的左边和右边做同样的行为

    再次递归发现.3右边只有一个元素或者没有元素,就代表有序了.4默认有序

    3.代码实现挖坑法

    第一步 快排的时候需要找基准

    第二步,分别递归左边和右边

    左边:

    右边

    第三步 递归结束条件

    也就是left>=right

    1. /**
    2. * 快速排序
    3. */
    4. public static void quickSort(int[] array) {
    5. quick(array,0,array.length-1);
    6. }
    7. public static void quick(int[]array,int left,int right){
    8. if(left>=right) return;
    9. int pivot=partition(array,left,right);
    10. quick(array,left,pivot-1);//分支左边
    11. quick(array,pivot+1,right);
    12. }
    13. public static int partition(int[] array,int start,int end){
    14. int tmp=array[start];
    15. while(start>end){
    16. if(start>end&&array[end]>tmp){
    17. end--;
    18. }
    19. //end遇到tmp小的,就放到start的位置
    20. array[start]=array[end];
    21. if(start>end&&array[start]<=tmp){
    22. start++;
    23. }
    24. //start遇到比tmp大的,就放到end的位置
    25. array[end]=array[start];
    26. }
    27. //到这里,start与end相遇
    28. array[start]=tmp;
    29. return start;
    30. }

    4.分析

    每一层都需要n 一共有logn 所以就是相乘

    空间复杂度就是

    1. * 时间复杂度:
    2. * 最好【每次可以均匀的分割待排序序列】:O(N*logn)
    3. * 最坏:数据有序 或者逆序的情况 O(N^2)
    4. * 空间复杂度:
    5. * 最好:O(logn)
    6. * 最坏:O(n) 单分支的一棵树
    7. * 稳定性:不稳定的排序
    8. * @param array
    9. */

    最坏的情况下就是有序的树,

    他是数据敏感的

    跟对排类似,但是前面的k要小

    如果对空间复杂度没有要求.用快排

    对空间复杂度又要求 用堆排或者归并

    不可以不取等号

    不然的话,遇到两个数相等的情况,进不了if语句

    end和start就一直互相换

    因为递归需要在栈上开辟内存,

    idea可以设置栈的大小

    四.字符串转整数

    先看几种情况

    字符串底层是一个数组

    是被final修饰不可以改.

    字符串转整数如果用自带的方法就是

    Integer.valueof(String)

    如果自己用就是

    要注意这两种情况的关系

    一个是不指向任何对象.一个是有对象,但是对象里面是空的

    1.字符串方法

    1. import java.util.*;
    2. public class Main{
    3. public static void main(String[] args){
    4. Scanner sc=new Scanner(System.in);
    5. while(sc.hasNext()){
    6. String str=sc.nextLine();
    7. if(str==null||str.isEmpty()) return;
    8. int flg=0;
    9. if(str.charAt(0)=='+'){
    10. flg=1;
    11. }
    12. if(str.charAt(0)=='-'){
    13. flg=-1;
    14. }
    15. int sum=0;
    16. for(int i=0;i
    17. if(i==0){
    18. if(flg==0){
    19. if(str.charAt(i)<'0'||str.charAt(i)>'9'){
    20. //System.out.println(sum);
    21. break;
    22. }
    23. if(str.charAt(i)==0){
    24. break;
    25. }
    26. sum=(str.charAt(i)-'0');
    27. }
    28. }else{
    29. if(str.charAt(i)<'0'||str.charAt(i)>'9'){
    30. sum=0;break;
    31. }
    32. sum=sum*10+(str.charAt(i)-'0');
    33. }
    34. }
    35. if(flg==0) flg=1;
    36. System.out.println(flg*sum);
    37. }
    38. }
    39. }

    因为字符串本身不能改变所以只能用这样的方式不停地比较.

    如果用字符数组把第一个是+-号的改成0即可.

    2.字符数组方法

    1. import java.util.*;
    2. public class Solution {
    3. public int StrToInt(String str) {
    4. //Scanner sc=new Scanner(System.in);
    5. if(str==null||str.isEmpty()) return 0;
    6. int sum=0;
    7. // String str=sc.nextLine();
    8. char[] arr=str.toCharArray();
    9. int flg=1;
    10. if(arr[0]=='+'){
    11. // flg=1;
    12. arr[0]='0';
    13. }
    14. if(arr[0]=='-'){
    15. flg=-1;
    16. arr[0]='0';
    17. }
    18. for(int i=0;i
    19. if(arr[i]<'0'||arr[i]>'9'){
    20. sum=0; break;
    21. }
    22. sum=sum*10+arr[i]-'0';
    23. }
    24. return sum*flg;
    25. }
    26. }

    3.sb方法

    1. import java.util.*;
    2. public class Solution {
    3. public int StrToInt(String str) {
    4. if(str.length()==0) return 0;
    5. StringBuilder sb=new StringBuilder();
    6. if(str.charAt(0)!='+'&&str.charAt(0)!='-'){
    7. if(str.charAt(0)>='0'&&str.charAt(0)<='9'){
    8. sb.append(str.charAt(0));
    9. }else{
    10. return 0;
    11. }
    12. }//不是加减的情况
    13. int flg=1;
    14. if(str.charAt(0)=='-'){
    15. flg=-1;
    16. }
    17. for(int i=1;i
    18. if(str.charAt(i)<'0'||str.charAt(i)>'9'){
    19. return 0;
    20. }else{
    21. sb.append(str.charAt(i));
    22. }
    23. }
    24. sb.reverse();
    25. int sum=0;
    26. int m=1;
    27. int n=0;
    28. for(int i=0;i
    29. n=(int)sb.charAt(i)-48;
    30. sum+=n*m;
    31. m*=10;
    32. }
    33. return sum*flg;
    34. }
    35. }

    五.笔试强训

  • 相关阅读:
    分布式理论和分布式锁知识点总结
    51单片机-蜂鸣器
    【自用重要】概率论中θ和θ尖的区别【计算时的一般方法】
    每日一题 1333. 餐厅过滤器(中等)
    有了这45个小技巧,再也不怕女朋友代码写得烂了!!
    在 IDEA 里下个五子棋不过分吧?
    【launch启动文件播放数据包】
    【iOS第三周总结】- UI学生管理系统
    web网页设计期末课程大作业:环境保护主题网站设计——农业三级带表单带js(14页)HTML+CSS+JavaScript
    深度学习库 SynapseML for .NET 发布0.1 版本
  • 原文地址:https://blog.csdn.net/m0_72618437/article/details/128140868