数据结构中的7种排序算法

数据结构中的7种排序算法

排序是将一个记录的任意序列重新排列成一个按键值有序的序列。
时间复杂度主要考虑元素的移动次数。
结构如下:
这里写图片描述

1.直接插入排序

1,定义:依次将待排序序列中的每一个记录插入到一个已经排好序的序列中,直到全部记录都排好序。
2,时间复杂度:在最好情况下,待排序序列为正序,时间复杂度为O(n);最坏情况下,待排序序列为逆序,时间复杂度为O(n^2);平均情况下,时间复杂度为O(n^2)。
3,空间复杂度:O(1)。

public static void insertSort(int[] nums){//直接插入排序

        for(int i=1;i<nums.length;i++){
            for(int j=i;j>0;j--){
                if(nums[j]<nums[j-1]){                  
                    int temp=nums[j];
                    nums[j]=nums[j-1];
                    nums[j-1]=temp; 
                }   

            }

            System.out.print(i+":");
            for(int a:nums) 
                System.out.print(a+" ");
            System.out.println();
        }

    }

示例数组:{12,5,9,20,6,31,24}
结果:这里写图片描述

2.希尔排序

1,希尔排序是对直接插入排序的改进。
2,定义:先将整个待排序序列记录序列分割为若干个子序列,在子序列内分别进行直接插入排序,待整个序列中的记录基本有序时,再对全体记录进行一次直接插入排序。
3,时间复杂度:O(nlogn)~O(n^2)。
4,空间复杂度:O(1).

public static void shellSort(int[] nums){//希尔排序

        int d=nums.length/2;//增量大小
        while(d>0){

            int k=0;//控制量
            while(k<d){

                //进行直接插入排序
                for(int i=k;i<nums.length;i=i+d){
                    for(int j=i;j>0&&j-d>=0;j=j-d){
                        if(nums[j]<nums[j-d]){                  
                            int temp=nums[j];
                            nums[j]=nums[j-d];
                            nums[j-d]=temp; 
                        }                       
                    }                   
                }   

             k++;//控制量增加

            }//while

            System.out.print(d+":");
            for(int a:nums) 
                System.out.print(a+" ");
            System.out.println();

            d=d/2;

         }//while
    }

示例数组:{12,5,9,20,6,31,24}
结果:这里写图片描述

3.冒泡排序

1,定义:两两比较相邻记录的关键码,如果是反序则交换,直到没有反序的记录为止。
2,时间复杂度:在最好情况下,待排序序列为正序。其时间复杂度为O(n);在最坏情况下,待排序序列为逆序,时间复杂度为O(n^2),平均时间复杂度为O(n^2).
3,空间复杂度:O(1)。

public static void bubbleSort(int[] nums){//冒泡排序
        for(int i=nums.length-1;i>0;i--){

            for(int j=0;j<i;j++){
                if(nums[j]>nums[j+1]){
                    int temp=nums[j];
                    nums[j]=nums[j+1];
                    nums[j+1]=temp;
                }
            }
            System.out.print(nums.length-i+":");
            for(int a:nums) 
                System.out.print(a+" ");
            System.out.println();
        }

    }

示例数组:{12,5,9,20,6,31,24}
结果:这里写图片描述

4.快速排序

1,快速排序是对冒泡排序的改进。
2,定义:首先选一个轴值,将待排序记录分割成独立的两部分,左侧记录的关键字均小于或者等于轴值,右边记录的关键字均大于或者等于轴值,然后分别对这两部分重复上述过程,直到整个序列有序。
3,在最好情况下,每次划分轴值的左侧子序列与右侧子序列的长度相同,时间复杂度为O(nlogn),在最坏情况下,待排序序列为正序或逆序,时间复杂度为O(n^2);平均情况下,时间复杂度为O(nlogn)。
4,空间复杂度:O(logn)。

public static void quickSort(int[] nums,int low ,int high){//快速排序

        if(low<high) {          
                int dp=partition(nums,low,high);
                quickSort(nums,low,dp-1);
                quickSort(nums,dp+1,high);                          

        }else{
            return;
        }       

    }
    public static int partition(int[] nums,int low ,int high){

        int pivot=nums[low];
        while(low<high){

            while(low < high && nums[high]>=pivot)
                high--;         
            nums[low]=nums[high];


            while(low < high && nums[low]<=pivot)
                low++;

            nums[high]=nums[low];

        }
        nums[low]=pivot;//此时low等于high,所以,也可以写成nums[high]=pivot;

        return low; //此时low等于high,所以返回任意一个都是正确的 
    }

示例数组:{12,5,9,20,6,31,24}
结果:这里写图片描述

5.简单选择排序

1,定义:第i趟通过n-i次关键码的比较,在n-i-1(1<=i<=n-1)个记录中选取关键码最小的记录,并和第i个记录交换作为有序序列的第i个记录。
2,时间复杂度:最好,最坏,平均的时间复杂度都是O(n^2)。
3,空间复杂度:O(1)。

        public static void selectSort(int[] nums){//简单选择排序
        for(int i=0;i<nums.length-1;i++){
            int sIndex=i;//最小数下标
            int sNum=nums[i];//最小数大小        
            for(int j=i+1;j<nums.length;j++){
                if(nums[j]<sNum){
                    sIndex=j;
                    sNum=nums[j];
                }

            }
            //交换
            int temp=nums[i];
            nums[i]=nums[sIndex];
            nums[sIndex]=temp;

            System.out.print(i+1+":");
            for(int a:nums) 
                System.out.print(a+" ");
            System.out.println();

        }
    }

示例数组:{12,5,9,20,6,31,24}
结果:这里写图片描述

6.堆排序

1,堆排序是对简单选择排序的改进。
2,首先将待排序的记录序列构造成一个堆,此时,选出了堆中所有记录的最大者即堆顶记录,然后将他从堆中移走,并将剩下的记录再调整成堆,这样又找出了次大的记录,以此类推,直到堆中只有一个记录为止。
3,时间复杂度:最好,最坏,平均的时间复杂度都是O(nlogn)。
4,空间复杂度:O(nlogn)。

public static void heapSort(int[] nums) {//堆排序
    if (nums == null || nums.length <= 1) {
         return;
    }

    buildMaxHeap(nums);//调用建立堆的函数

    //将堆顶元素调整至数组最后,然后,将当前堆继续调整为大顶堆
    for (int i = nums.length - 1; i >= 1; i--) {

        int temp=nums[0];
        nums[0]=nums[i];
        nums[i]=temp;

        maxHeap(nums, i, 0);


        System.out.print(nums.length-i+":");
        for(int a:nums) 
        System.out.print(a+" ");
        System.out.println();
    }
}

private static void buildMaxHeap(int[] nums) {//建立堆
    if (nums == null || nums.length <= 1) {
        return;
    }

    int half = nums.length / 2;
    for (int i = half; i >= 0; i--) {
        maxHeap(nums, nums.length, i);
    }
}

private static void maxHeap(int[] nums, int heapSize, int index) {//递归调整为大顶堆

    int left = index * 2 + 1;
    int right = index * 2 + 2;

    if( left > heapSize && right > heapSize ){
           //没有这个return,也是正确的,好吧!我没有看懂~
           return;
    }

    int largest = index;
    if (left < heapSize && nums[left] > nums[index]) {
        largest = left;
    }

    if (right < heapSize && nums[right] >nums[largest]) {
        largest = right;
    }

    if (index != largest) {         
        int temp=nums[index];
        nums[index]=nums[largest];
        nums[largest]=temp;

        maxHeap(nums, heapSize, largest);
    }


}

示例数组:{12,5,9,20,6,31,24}
结果:这里写图片描述
代码参考链接

7.二路归并排序

1,定义:将若干个有序序列进行两两归并,直至所有待排记录都在一个有序序列为止。
2,时间复杂度:最好,最坏,平均都是O(nlogn)。
3,空间复杂度:O(n)。

 public static void mergeSort(int[] a, int left, int right) {

       if(left<right){

           //int center = (left + right) >> 1;
           int center=(left+right)/2;
           mergeSort(a, left, center);
           mergeSort(a, center + 1, right);
           merge(a, left, center, right);
        }else{

            return;
        }
}

    public static void merge(int[] data, int left, int center, int right) {
        int[] tmpArr = new int[right+1];
        int mid = center + 1;
        int index = left; // index记录临时数组的索引
        int tmp = left;

        // 从两个数组中取出最小的放入中临时数组
        while (left <= center && mid <= right) {
            tmpArr[index++] = (data[left] <= data[mid]) ? data[left++]: data[mid++];
        }
        // 剩余部分依次放入临时数组
        while (mid <= right) {
            tmpArr[index++] = data[mid++];
        }
        while (left <= center) {
            tmpArr[index++] = data[left++];
        }
        // 将临时数组中的内容复制回原数组
        for (int i = tmp; i <= right; i++) {
            data[i] = tmpArr[i];
        }
        System.out.println(Arrays.toString(data));
 }

    public static void main(String[] args) {
        int[] arr={12,5,9,20,6,31,24};
        mergeSort(arr, 0, arr.length-1);
    }

示例数组:{12,5,9,20,6,31,24}
结果:这里写图片描述
代码参考链接

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是七常见的排序算法及其基本原理: 1. 冒泡排序(Bubble Sort): - 基本原理:比较相邻的两个元素,如果顺序错误则交换位置,每次循环将最大的元素移动到末尾。 - 代码示例: ```python def bubble_sort(arr): n = len(arr) for i in range(n-1): for j in range(n-i-1): if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] return arr ``` 2. 选择排序(Selection Sort): - 基本原理:每次从未排序的部分选择最小的元素,放到已排序部分的末尾。 - 代码示例: ```python def selection_sort(arr): n = len(arr) for i in range(n-1): min_idx = i for j in range(i+1, n): if arr[j] < arr[min_idx]: min_idx = j arr[i], arr[min_idx] = arr[min_idx], arr[i] return arr ``` 3. 插入排序(Insertion Sort): - 基本原理:将未排序的元素逐个插入到已排序部分的正确位置。 - 代码示例: ```python def insertion_sort(arr): n = len(arr) for i in range(1, n): key = arr[i] j = i - 1 while j >= 0 and arr[j] > key: arr[j+1] = arr[j] j -= 1 arr[j+1] = key return arr ``` 4. 希尔排序(Shell Sort): - 基本原理:将待排序的元素按照一定的间隔分组,对每组使用插入排序,逐渐缩小间隔直至为1。 - 代码示例: ```python def shell_sort(arr): n = len(arr) gap = n // 2 while gap > 0: for i in range(gap, n): temp = arr[i] j = i while j >= gap and arr[j-gap] > temp: arr[j] = arr[j-gap] j -= gap arr[j] = temp gap //= 2 return arr ``` 5. 归并排序(Merge Sort): - 基本原理:将待排序的序列递归地分成两半,对每半进行排序,然后将两个有序的半合并成一个有序序列。 - 代码示例: ```python def merge_sort(arr): if len(arr) <= 1: return arr mid = len(arr) // 2 left = merge_sort(arr[:mid]) right = merge_sort(arr[mid:]) return merge(left, right) def merge(left, right): result = [] i = j = 0 while i < len(left) and j < len(right): if left[i] < right[j]: result.append(left[i]) i += 1 else: result.append(right[j]) j += 1 result.extend(left[i:]) result.extend(right[j:]) return result ``` 6. 快速排序(Quick Sort): - 基本原理:选择一个基准元素,将小于基准的元素放在左边,大于基准的元素放在右边,然后递归地对左右两部分进行快速排序。 - 代码示例: ```python def quick_sort(arr): if len(arr) <= 1: return arr pivot = arr[len(arr) // 2] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quick_sort(left) + middle + quick_sort(right) ``` 7. 堆排序(Heap Sort): - 基本原理:将待排序的序列构建成一个大顶堆,然后依次取出堆顶元素并调整堆,直到堆为空。 - 代码示例: ```python def heap_sort(arr): n = len(arr) for i in range(n // 2 - 1, -1, -1): heapify(arr, n, i) for i in range(n-1, 0, -1): arr[i], arr[0] = arr[0], arr[i] heapify(arr, i, 0) return arr def heapify(arr, n, i): largest = i left = 2 * i + 1 right = 2 * i + 2 if left < n and arr[left] > arr[largest]: largest = left if right < n and arr[right] > arr[largest]: largest = right if largest != i: arr[i], arr[largest] = arr[largest], arr[i] heapify(arr, n, largest) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值