数据结构 --- 排序

插入排序:简单插入排序、希尔排序

交换排序:冒泡排序、快速排序

选择排序:简单选择排序

1.简单插入排序

算法思想:

   设输入的待排序的数组为nums[0..n-1],假设nums[0]已排好序,num为哨兵元素

   依次将nums[i](i = 1,2,...,n-1)从后往前插入到前面已排好序的子数组nums[0,..,i-1]中的合适位置

算法示意图:

Java实现:

     public static void main(String[] args) {
        insertSort(new int[]{3,0,4,1,5,7,11});
     }

      /**
      * 插入排序
      */
     public static void insertSort(int[] nums) {
         int num;
         for (int i = 1; i < nums.length; i++) {
             num = nums[i - 1]; // 哨兵
             if (nums[i] < num) {
                 num = nums[i];
                 int j = i - 1;
                 for (; j >= 0 && num < nums[j]; --j) {
                     nums[j+1] = nums[j];
                 }
                 nums[j+1] = num;
             }
         }
         for (int k = 0; k < nums.length; k++) {
             if (k == nums.length - 1) {
                 System.out.print(nums[k]);
             } else {
                 System.out.print(nums[k]);
                 System.out.print(",");
             }
         }
     }

运行结果:0,1,3,4,5,7,11

时间复杂度:

最好情况O(n)、平均情况O(n^2)、最坏情况O(n^2)

空间复杂度:

O(1)

是否稳定:

稳定

2.希尔排序(缩小增量排序)

算法思想:

希尔排序是对插入排序进行改进得到的一种排序算法,希尔排序加入了多趟预排序,正是这多趟预排序,让它的时间复杂度降低了不少。
1>选取一个小于n的步长d_{1},把表中全部的数据分成d_{1}个组,所有距离为d_{1}的倍数的数据放在同一个组,在各组中进行直接插入排序;

2>选取第二个步长d_{2} < d_{1},重复上述步骤,直到所取到的d_{t} = 1,此时所有的数据已放到同一组中,最后再进行一次直接插入排序。

算法示例图:

Java实现:

public static void main(String[] args) throws InterruptedException {
        shellSort(new int[]{3,0,4,1,5,7,11});
     }

     /**
      * 希尔排序
      */
     public static void shellSort(int[] nums) {
         int num;
         for (int dk = nums.length/2; dk >= 1; dk /= 2) {
             for (int i = dk; i < nums.length; i++) {
                 num = nums[i - dk]; // 哨兵
                 if (nums[i] < num) {
                     num = nums[i];
                     int j = i - dk;
                     for (; j >= 0 && num < nums[j]; j -= dk) {
                         nums[j+dk] = nums[j];
                     }
                     nums[j+dk] = num;
                 }
             }
         }
         for (int k = 0; k < nums.length; k++) {
             if (k == nums.length - 1) {
                 System.out.print(nums[k]);
             } else {
                 System.out.print(nums[k]);
                 System.out.print(",");
             }
         }
     }

运行结果:0,1,3,4,5,7,11

时间复杂度:

平均情况O(n^1.3)

空间复杂度:

O(1)

是否稳定:

不稳定

3.冒泡排序

算法思想:
冒泡排序是一种交换排序,它的基本思想是:两两比较相邻的关键字,如果反序则交换,直到没有反序的记录为止。一般都是从最末尾开始比较,逐个向上冒。冒泡的思想重点是相邻之间的比较,可以看出一个循环完毕之后,第一位一定是一个最小的数,但与此同时在中间的过程中,我们同样可以看到相对小的数也会向上移动,最终都会形成有序的序列。
算法示意图:

Java实现:

  public static void main(String[] args) {
        bubbleSort(new int[]{3,0,4,1,5,7,11});
      }
    
     /**
      * 冒泡排序
     */
     public static void bubbleSort(int[] nums) {
         boolean flag = false;
         for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums.length - 1 - i; j++) {
              if (nums[j] > nums[j+1]) {
                 int num = nums[j];
                 nums[j] = nums[j+1];
                 nums[j+1] = num;
                 flag = true; 
              }
           }
               if (!flag) break;
         }
        for (int k = 0; k < nums.length; k++) {
           if (k == nums.length - 1) {
               System.out.print(nums[k]);
           } else {
               System.out.print(nums[k]);
               System.out.print(",");
            }
          }
         }

运行结果:0,1,3,4,5,7,11

时间复杂度:

最好情况O(n)、平均情况O(n^2)、最坏情况O(n^2)

空间复杂度:

O(1)

是否稳定:

稳定

4.快速排序

算法思想:

1>在表中任取某个节点num作为基准值,将数组nums[left,...,right]划分为两个子数组nums[left,...,index-1]和nums[index+1,...,right],其中nums[left,...,index-1]中的每个元素都小于等于num,nums[index+1,...,right]中的每个元素都大于等于num;

2>通过递归调用快速排序,对子数组nums[left,...,index-1]和nums[index+1,...,right]执行上述操作。

算法示例图:

Java实现:

     public static void main(String[] args) {
         int[] nums = new int[]{3,0,4,1,5,7,11};
         quickSort(nums,0,nums.length - 1);
         for (int k = 0; k < nums.length; k++) {
             if (k == nums.length - 1) {
                 System.out.print(nums[k]);
             } else {
                 System.out.print(nums[k]);
                 System.out.print(",");
             }
         }
      }

     /**
      * 快速排序
     */
     public static void quickSort(int[] nums, int left, int right) {
         if (left < right) {
             int index = partition(nums,left,right);
             quickSort(nums, left, index -1);
             quickSort(nums, index + 1, right);
         }
     }

    public static int partition(int[] nums, int left, int right) {
         int num = nums[left];
         while(left < right) {
             while(left < right && num <= nums[right]) --right;
             nums[left] = nums[right];
             while(left < right && num >= nums[left]) ++ left;
             nums[right] = nums[left];
         }
         nums[left] = num;
         return left;
   }

运行结果:0,1,3,4,5,7,11

时间复杂度:

最好情况O(nlog_{2}n )、平均情况O(nlog_{2}n)、最坏情况O(n^2)

空间复杂度:

O(log_{2}n)

是否稳定:

不稳定

5.简单选择排序

算法思想:

将最小元素找出并放在序列的最前面,在剩下的元素中继续找出最小的元素放在第二个位置上,以此类推,每次选出一个元素,即可确定其在有序序列中的最终位置。

算法示例图:

Java实现:

     public static void main(String[] args) {
         int[] nums = new int[]{3,0,4,1,5,7,11};
         selectSort(nums);
      }

     /**
      * 简单选择排序
     */
     public static void selectSort(int[] nums) {
         int length = nums.length;
         for (int i = 0; i < length - 1; i++) {
             int min = i;
             for (int j = i + 1; j < length;j++) {
                 if (nums[min] > nums[j]) {
                     min = j;
                 }
             }
             if (min != i) {
                 int flag = nums[min];
                 nums[min] = nums[i];
                 nums[i] = flag;
             }
         }
         for (int k = 0; k < nums.length; k++) {
             if (k == nums.length - 1) {
                 System.out.print(nums[k]);
             } else {
                 System.out.print(nums[k]);
                 System.out.print(",");
             }
         }
     }

运行结果:0,1,3,4,5,7,11

时间复杂度:

最好情况O(n^2)、平均情况O(n^2)、最坏情况O(n^2)

空间复杂度:

O(1)

是否稳定:

不稳定

发布了42 篇原创文章 · 获赞 3 · 访问量 3910

猜你喜欢

转载自blog.csdn.net/zhangting19921121/article/details/104411653