排序算法(一)

排序算法分类

排序算法可以分为两大类:比较排序和非比较排序
比较排序:可以分为交换排序,插入排序,选择排序和归并排序
交换排序:冒泡排序和快速排序
插入排序:简单插入排序、希尔排序
选择排序:简单选择排序、堆排序
归并排序:二路归并排序、多路归并排序
分比较排序:可以分为计数排序,桶排序和基数排序;
一共是11种排序;

排序算法(一)

; 题目

给你一个整数数组 nums,请你将该数组升序排列。

冒泡排序

概念:把最大的换到最后一位,第二大的换到倒数第二位;

冒泡写法:

//原始写法,每一遍都交换n次
public int[] maopao(int[] nums){
    for(int i=0;i<nums.length-1;i++){ int max="0;" for(int j="i+1;j<nums.length;j++){" if(nums[i]>nums[j]){
              int tmp = nums[i];
              nums[i] = nums[j];
              nums[j] = tmp;
            }
        }
    }
    return nums;
}

//&#x4F18;&#x5316;&#x5185;&#x5FAA;&#x73AF;&#xFF0C;&#x4EA4;&#x6362;&#x4E00;&#x6B21;&#xFF0C;&#x6BCF;&#x6B21;&#x53EA;&#x4EA4;&#x6362;&#x4E00;&#x6B21;
public int[] maopao(int[] nums){
    for(int i=0;i<nums.length-1;i++) { int max="50000," idx="0;" for (int j="i" + 1; < nums.length; j++) if (nums[j] max) } if(nums[i]>max){
            int tmp = nums[i];
            nums[i] = nums[idx];
            nums[idx] = tmp;
        }
    }
    return nums;
}

//&#x4F18;&#x5316;&#x4E09; &#xFF0C;&#x5BF9;&#x5DF2;&#x7ECF;&#x6709;&#x5E8F;&#x7684;&#x5E8F;&#x5217;&#x505C;&#x6B62;&#x6392;&#x5E8F;
public static void MaoPao(int[] arr) {
        int length = arr.length;
        boolean flag = true;
        //&#x5916;&#x5C42;&#x5FAA;&#x73AF;&#x63A7;&#x5236;&#x8F6E;&#x6570;&#xFF1A;
        for (int i = 0; i < length - 1; i++) {
              //&#x5185;&#x5B58;&#x5FAA;&#x73AF;&#x8FDB;&#x884C;&#x6BD4;&#x8F83;&#xFF1A;
              //&#x5982;&#x679C;&#x5185;&#x5FAA;&#x73AF;&#x6574;&#x4E2A;&#x4E00;&#x8F6E;&#x4E0B;&#x53BB;&#xFF0C;&#x4E00;&#x6B21;&#x4EA4;&#x6362;&#x4E5F;&#x6CA1;&#x6709;&#x53D1;&#x751F;&#xFF0C;
              //&#x8BF4;&#x660E;&#x6B64;&#x65F6;0~length-1-i&#x4E4B;&#x95F4;&#x7684;&#x5143;&#x7D20;&#x90FD;&#x5DF2;&#x7ECF;&#x662F;&#x6709;&#x5E8F;(&#x5347;&#x5E8F;)&#x7684;&#x4E86;&#xFF0C;
              // &#x800C;&#x4E14;&#x6211;&#x4EEC;&#x4E5F;&#x77E5;&#x9053;length-1-i~length-1&#x4E4B;&#x95F4;&#x7684;&#x5143;&#x7D20;&#x4E5F;&#x662F;&#x521A;&#x521A;&#x5192;&#x6CE1;&#x6392;&#x5E8F;&#x597D;&#x7684;&#x6709;&#x5E8F;&#x5E8F;&#x5217;&#xFF0C;
              // &#x90A3;&#x4E48;&#x6B64;&#x65F6;&#x8BF4;&#x660E;&#xFF0C;&#x6574;&#x4E2A;&#x6570;&#x7EC4;&#x5176;&#x5B9E;&#x90FD;&#x5DF2;&#x7ECF;&#x662F;&#x6709;&#x5E8F;&#x7684;&#x4E86;&#xFF0C;&#x5C31;&#x6CA1;&#x6709;&#x5FC5;&#x8981;&#x518D;&#x7EE7;&#x7EED;&#x904D;&#x5386;&#x548C;&#x6BD4;&#x8F83;&#x4E0B;&#x53BB;&#x4E86;&#x3002;
              for (int j = 0; j < length - 1 - i; j++) {
                    if (arr[j] > arr[j + 1]) {
                          int temp = arr[j];
                          arr[j] = arr[j + 1];
                          arr[j + 1] = temp;
                          flag = false;
                    }
              }
              //&#x6240;&#x4EE5;&#x6211;&#x4EEC;&#x8BBE;&#x7F6E;&#x4E00;&#x4E2A;flag&#xFF0C;&#x5982;&#x679C;&#x5185;&#x5FAA;&#x73AF;&#x6574;&#x4E2A;&#x4E00;&#x8F6E;&#x4E0B;&#x53BB;&#xFF0C;&#x4E00;&#x6B21;&#x4EA4;&#x6362;&#x4E5F;&#x6CA1;&#x6709;&#x53D1;&#x751F;&#x7684;&#x65F6;&#x5019;&#xFF0C;flag&#x4E3A;true&#xFF0C;&#x8DF3;&#x51FA;&#x6240;&#x6709;&#x5FAA;&#x73AF;&#xFF1B;
              if (flag) {
                    break;
              }
        }
  }

</nums.length-1;i++)></nums.length-1;i++){>

上面是最原始的冒泡和对冒泡优化后的两种算法,极端情况下这两种算法在对数组排序后都会超时;这时候就要考虑同为交换排序的快速排序;

快速排序

概念:选定一个标准值,比这个标准值大的放在右边,小的放在左边;

   public void  quickSort(int[] nums,int left,int right) {
        if(left>=right){
            return;
        }
        int le = left;
        int ri = right;
        //getMid(nums,left,right);
        int povit = nums[left];

        while (le< ri) {
            while (povit <= nums[ri] && le < ri) ri--; swap(nums,le,ri); while (nums[le] le++; swap(nums,le ,ri); } nums[le]="povit;" quicksort(nums,left,le-1); quicksort(nums,le+1,right); public void swap(int[] nums,int a,int b){ int tmp="0;" if(nums[a]>nums[b]){
            tmp = nums[a];
            nums[a] = nums[b];
            nums[b] = tmp;
        }
    }
</=>

简单插入排序

概念:使用双层for循环实现,外层for循环实现n+1的遍历(n是前面已经有序的数组,1是新增要排序的数据),内层for循环实现对插入位置的查找;
代码如下:

public void  chaRu(int[] nums){
        int l = nums.length;
        for(int i =0 ;i<l;i++){ int tmp="nums[i];" j="i-1;" while(j>=0 && nums[j]>tmp){
                nums[j+1] = nums[j];
                j--;
                }
            nums[j+1] = tmp;
        }
    }
</l;i++){>

排序算法(一)

希尔排序

概念:是按照不同步长对元素进行插入排序,将整个有序序列分割成若干个子序列分别进行插入排序;
代码如下:

public void xier(int[] nums){
        int l = nums.length;
        for(int dk= l/2;dk>=1;dk = dk/2){
            for(int i =dk ;i<l;i++){ int tmp="nums[i];" j="i-dk;" while(j>=0 && nums[j]>tmp){
                    nums[j+dk] = nums[j];
                    j=j-dk;
                    }
                nums[j+dk] = tmp;
            }
        }
    }
</l;i++){>

选择排序

原理:先扫描整个数组,已找到最小元素并将这个元素与第一个元素交换;然后从最第二个元素开始扫描找出最小元素与第二数交换;不断重复这个过程;
代码如下(不要和冒泡排序搞混了):

public void xuanze(int[] nums){
        int l = nums.length;
        for(int i=0;i<l-1;i++){ int min="50000,idx=0;" for(int j="i+1;j<l;j++){" if(nums[j]<min) idx="j;" } if(min<nums[i]){ tmp="nums[i];" nums[i]="nums[idx];" nums[idx]="tmp;" < code></l-1;i++){>

堆排序

概念:堆是一种叫做完全二叉树的数据结构,可以分为大根堆,小根堆,而堆排序就是基于这种结构而产生的一种算法
原理:大根堆每个节点的值都大于或者等于子节点左右孩子节点的值
小根堆每个节点都小于或者等于子节点左右孩子节点的值
排序思想:
(1)首先将代排的数组构成一个大根堆,此时,整个数组的最大值就是堆结构的顶端
(2)将顶端的数与末尾的数交换,此时,末尾的数为最大值,待排序列长度为n-1;
(3)将剩下的n-1个数重构大根堆。在将顶端数与n-1位置的数进行交换,如此反复执行便能得到有序数组。
代码如下:

 //&#x5806;&#x6392;&#x5E8F;
   void adjust(vector<int> &nums, int len, int index){
        int left = 2*index + 1; // index&#x7684;&#x5DE6;&#x5B50;&#x8282;&#x70B9;
        int right = 2*index + 2;// index&#x7684;&#x53F3;&#x5B50;&#x8282;&#x70B9;
        int maxIdx = index;
        if(left<len && nums[left]> nums[maxIdx])     maxIdx = left;
        if(right<len && nums[right]> nums[maxIdx])     maxIdx = right;

    if(maxIdx != index)
    {
        swap(nums[maxIdx], nums[index]);
        adjust(nums, len, maxIdx);
    }

}

// &#x5806;&#x6392;&#x5E8F;
    void HeapSort(vector<int> &nums, int size){
       for(int i=size/2 - 1; i >= 0; i--){
            adjust(nums, size, i);
        }
         for(int i = size - 1; i >= 1; i--){
                swap(nums[0], nums[i]);
                adjust(nums, i, 0);
            }
        }
};
</int></len></len></int>

二路归并排序

概念和原理:二路归并排序又称合并排序
图片:

排序算法(一)
void mergeSortInOrder(int[] arr,int bgn,int mid, int end){
        int l = bgn, m = mid +1, e = end;
        int[] arrs = new int[end - bgn + 1];
        int k = 0;
        while(l <= mid && m <="e){" if(arr[l] arr[m]){ arrs[k++]="arr[l++];" }else{ } while(l while(m for(int i="0;" arrs.length; i++){ arr[i + bgn]="arrs[i];" void mergesort(int[] arr, int bgn, end) { if(bgn>= end){
            return;
        }
        int mid = (bgn + end) >> 1;
        mergeSort(arr,bgn,mid);
        mergeSort(arr,mid + 1, end);
        mergeSortInOrder(arr,bgn,mid,end);
    }
</=>

归并排序和堆排序都是使用了回溯的方法,在实际过程中回溯很有可能代表着超时,那么两种算法就了解即可。

Original: https://blog.csdn.net/younger_to_older/article/details/127808284
Author: 布吃
Title: 排序算法(一)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/656348/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球