简述八大排序(Sort)

1.插入排序

1.1直接插入排序

给定一组数据,若数据只有一个肯定是有序的,我们将无序数据一个个插入到已有序的数据中。用i遍历无序数据,j遍历有序数据,找到合适插入位置,用tmp存放目标插入数据,将其与j对应数据对比,若大于j就放在j后面,小于j就把j数据往前移一位,j--再次判断。具体代码如下:

java 复制代码
 public static void insertSort(int [] array){
            for(int i=1;i<array.length;i++){
                int tmp=array[i];//无序数据
                int j=i-1;
                for(;j>=0;j--){
                    if(array[j]>tmp){
                       array[j+1]=array[j];
                    }
                    else{
                        array[j+1]=tmp;
                        break;
                    }
                }
                array[j+1]=tmp;
            }
    }

1.2希尔排序

希尔排序可以说时直插排序的plus版本,因为直接插入排序的特性是数据越有序排序越快,所以希尔排序会先把数据分成gap组,gap不固定,将每组中的数据进行排序,gap不断减小,最终当gap等于1时排序完毕。具体代码如下:

java 复制代码
 public static void shellSort(int [] array){
            int gap=array.length;
        while(gap>1){
            gap=gap/2;
            shell111(array,gap);
        }

    }
    private static void shell(int [] array ,int gap){
            for(int i=gap;i<array.length;i++){
                int tmp=array[i];
                int j=i-gap;
                for(;j>=0;j=j-gap){
                    if(array[j]>tmp){
                        array[j+gap]=array[j];
                    }
                    else {
                        array[j+gap]=tmp;
                        break;
                    }
                }
                array[j+gap]=tmp;
            }
    }

2.选择排序

2.1直接选择排序

思想:j从第一个开始遍历,每次遍历找到当前最小的值的下标,存入minIndex,然后跟下标为i的交换,随后i++,直到整个数据遍历完毕。具体代码实现:

java 复制代码
  public static void selectSort(int [] array){
        for(int i=0;i<array.length;i++){
            int minIndex=i;
            for(int j=i+1;j<array.length;j++){
                if(array[j]<array[minIndex]){
                    minIndex=j;//更新最小下标值
                }
            }
            swap(array,minIndex,i);
        }
    }

2.2堆排序

思想:先把一组数据建成堆(升序就大根堆,降序就小根堆),然后将堆首元素与堆尾元素交换,因为堆首元素一定是max/min值,具体代码如下:

java 复制代码
 public static void heapSort(int[] array){
        createHeap111(array);
        int end=array.length-1;
        while(end>0){
            swap(array,end,0);
            siftDown111(array,0,end-1);
            end--;
        }
    }
    private static void createHeap(int [] array){
        int parent=(array.length-2)/2;
        for(;parent>=0;parent--){
            siftDown111(array,parent,array.length-1);
        }

    }
    private static void siftDown(int[] array, int parent,int end) {
        int child=parent*2+1;
        while(child<=end){
            if(child+1<=end&&array[child]<array[child+1]){
                child++;
            }
            if(array[child]>array[parent]){
                swap(array,parent,child);
                parent=child;
                child=2*parent+1;
            }
            else{break;}

        }
    }

3.交换排序

3.1冒泡排序

比较i趟,每一趟都将找出当前范围的最小值/最大值,让它排到末尾,也就是每一趟都定义一个j,j从0开始遍历,如果j大于j+1就叫唤,然后j++,直到循环结束,这样一趟下来就能将一个最值交换到末尾。具体代码实现:

java 复制代码
  public static void bubbleSort(int [] array){
        for(int i=0;i<array.length-1;i++){
            for(int j=0;j<array.length-1-i;j++){
                if(array[j]>array[j+1]){
                    swap(array,j,j+1);
                }
            }
        }
    }

3.2快速排序(挖坑法)

思路;首先找出一个基准值tmp,通常由left对应值担任,当left值赋给tmp后,left就可以看作一个坑,此时right往前走,直到找到比tmp小的值将这个值"填"到left坑中,此时right也成了一个坑,left开始走,直到找到比tmp大的值将其"填"到right,就这样直到left和right相遇,这时将tmp"填"到相遇这个坑中。具体代码如下:

java 复制代码
public static void rapidSort(int [] array){
        rapid111(array,0,array.length-1);
}
private static void rapid(int [] array,int left,int right){
        if(left>=right){
            return;
        }
        int mid=getMid111(array,left,right);
        rapid111(array,0,mid-1);
        rapid111(array,mid+1,right);
}
private static int  getMid(int [] array,int left,int right){
        int tmp=array[left];
        while(left<right){
            while(left<right&&array[right]>tmp){
                right--;
            }
            array[left]=array[right];
            while(left<right&&array[left]<tmp){
                left++;
            }
            array[right]=array[left];

        }
        array[left]=tmp;
        return left;
}

4.归并排序

思想:将一大组数据分解成小组数据,然后将小组数据有序,然后将小组数据合并为大组数据。

所以整个过程就分为:分割------合并

先说分割:结束条件------left==right。若不满足,则计算mid,通过mid将该范围分割为两部分,具体代码如下:

java 复制代码
private static void mergeNum(int [] array,int left,int right){
if(left==right){
return ;}
int mid=(left+right)/2;
mergeNum(array,left,mid);
mergeNum(array,mid+1,right);
}

再说合并:假设有两组数据,设计变量s1 e1,s2 e2表示两组数据的头和尾,然后创建一个数组,按从小到大将两组数据放在数组中,然后将这个数组元素复制到array数组中对应的位置。具体代码如下:

java 复制代码
 private static void merge(int [] array,int left,int mid,int right){
        int [] num=new int[right-left+1];
        int k=0;
        int s1=left;
        int e1=mid;
        int s2=mid+1;
        int e2=right;
        while(s1<=e1&&s2<=e2){
            if(array[s1]<=array[s2]){
                num[k++]=array[s1++];
            }
            else{
                num[k++]=array[s2++];
            }
        }
        //必有一败  将剩余组数据放在数组
            while(s2<=e2){
                num[k++]=array[s2++];
            }
            while(s1<=e1){
                num[k++]=array[s1++];
            }
            //数组元素有序,还给array
        for(int i=0;i<num.length;i++){
            array[i+left]=num[i];
        }
        }

5.计数排序

具体代码如下:

java 复制代码
 public static void countSort(int [] array){
        int left=0;
        int right=array.length-1;
        int maxVal=array[0];
        int minVal=array[0];
        for(int i=1;i<array.length;i++){
            if(array[i]>maxVal){
                maxVal=array[i];
            }
            if(array[i]<minVal){
                minVal=array[i];
            }
        }
        int [] number=new int[maxVal-minVal+1];
        //初始化计数数组
            for(int i=0;i<array.length;i++){
                int index=array[i];
                number[index-minVal]++;
            }
            //将计数数组元素打印到原数组中
            int index=0;
            for(int i=0;i<number.length;i++){
                while(number[i]!=0){
                    array[index]=i+ minVal;
                    index++;
                    number[i]--;
                }
            }
        }
相关推荐
Code_流苏3 分钟前
Python趣学篇:从零打造智能AI井字棋游戏(Python + Tkinter + Minimax算法)
python·算法·游戏·tkinter·智能井字棋·minimax算法
Lu Yao_9 分钟前
【数据结构 -- B树】
数据结构·b树
理智的灰太狼12 分钟前
题目 3230: 蓝桥杯2024年第十五届省赛真题-星际旅行
算法·职场和发展·蓝桥杯
wcjwdq13 分钟前
“顶点着色器”和“片元着色器”是先处理完所有顶点再统一进入片元阶段,还是一个顶点处理完就去跑它的片元?
算法·着色器
技术帮扶户20 分钟前
Leetcode-7 寻找用户推荐人
算法·leetcode·职场和发展
VU-zFaith87039 分钟前
C++概率论算法详解:理论基础与实践应用
c++·算法·概率论
全栈凯哥1 小时前
Java详解LeetCode 热题 100(23):LeetCode 206. 反转链表(Reverse Linked List)详解
java·算法·leetcode·链表
kingmax542120081 小时前
动态规划十大经典题型状态转移、模版等整理(包括leetcode、洛谷题号)
算法·leetcode·动态规划
闪电麦坤951 小时前
数据结构:递归:自然数之和
数据结构·算法
t198751281 小时前
matlab实现求解兰伯特问题
开发语言·算法·matlab