8大排序算法图文讲解以及代码实现

1.直接插入排序:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。
在这里插入图片描述

public static void insertSort(int[] array){
        int j=0;
        for(int i=1;i<array.length;i++){
            int tmp=array[i];
            for(j=i-1;j>=0;j--){
                if(array[j]>tmp){
                    array[j+1]=array[j];
                }
                else {
                    break;
                }
            }
            array[j+1]=tmp;
        }
    }

2.希尔排序:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。

在这里插入图片描述

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

3.直接选择排序:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。

在这里插入图片描述

public static void selectSort(int[] array){
        for(int i=0;i<array.length;i++){
            for(int j=i+1;j<array.length;j++){
                if(array[i]>array[j]){
                    int tmp=array[i];
                    array[i]=array[j];
                    array[j]=tmp;
                }
            }
        }
    }

4.堆排序:是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是
通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。

在这里插入图片描述

 public void AdjustDown(int root, int len) {
        int parent=root;
        int child=2*parent+1;
        while (child<len){
            if(child+1<len && elem[child]<elem[child+1]){
                ++child;
            }
            //child下标存放的是左右孩子的最大值
            if(elem[child]>elem[parent]){
                //交换
                int tmp=elem[child];
                elem[child]=elem[parent];
                elem[parent]=tmp;
                parent=child;
                child=2*parent+1;
            }else{
                break;
            }
        }
    }
    public void heapSort() {
        int end=this.usedSize-1;
        while (end>0){
            int tmp=this.elem[0];
            this.elem[0]=this.elem[end];
            this.elem[end]=tmp;
            AdjustDown(0,end);
            end--;
        }
    }

5.冒泡排序:是一种交换排序,所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

在这里插入图片描述

public static void bubbleSort(int[] array){
        boolean flag=false;
        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]) {
                    int tmp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = tmp;
                    flag=true;
                }
            }
            if(!flag){
                break;
            }
        }
    }

6.快速排序是于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

在这里插入图片描述

  public static void quickSort2(int[] array){
         Stack<Integer> stack=new Stack<>();
         int low=0;
         int high=array.length-1;
         int par=partion(array,low,high);
         if(par>low+1){
             stack.push(low);
             stack.push(par-1);
         }
         if(par<high-1){
             stack.push(par+1);
             stack.push(high);
         }
         while (!stack.empty()){
             high=stack.pop();
             low=stack.pop();
            par=partion(array,low,high);
             if(par>low+1){
                 stack.push(low);
                 stack.push(par-1);
             }
             if(par<high-1){
                 stack.push(par+1);
                 stack.push(high);
             }
         }
    }

7.归并排序:是建立在归并操作上的一种有效的排序算法,将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤:
在这里插入图片描述
在这里插入图片描述
递归实现:

 //1.合并函数
    public static void merge(int[] array,int start,int mid,int end){
        int[] tmpArray=new int[array.length];
        int tepIndex=start;
        int s2=mid+1;
        int i=start;
        //当有两个归并段时
        while (start<=mid && s2<=end){
            if(array[s2]>=array[start]){
                tmpArray[tepIndex++]=array[start++];
            }else {
                tmpArray[tepIndex++]=array[s2++];
            }
        }
        //第一个归并段有数据
        while (start<=mid){
            tmpArray[tepIndex++]=array[start++];
        }
        //第二个归并段有数据
        while (s2<=end){
            tmpArray[tepIndex++]=array[s2++];
        }
        //把排好的数据从tmpArray拷贝到array
        while (i<=end){
            array[i]=tmpArray[i++];
        }
    }
    public static void mergeSort(int[] array,int start,int end){
        if(start>=end){
            return;
        }
        int mid=(start+end)/2;
        mergeSort(array,start,mid);
        mergeSort(array,mid+1,end);
        merge(array,start,mid,end);
    }

//非递归递归排序
       //归并
    public static void merge2(int[] array,int gap){
        int[] tmpArray=new int[array.length];
        int i=0;//tmpArray的下标
        int start1=0;
        int end1=start1+gap-1;
        int start2=end1+1;
        int end2=start2+gap-1<=array.length-1 ?
                start2+gap-1 : array.length-1;
        //保证有两个归并段
        while (start2<array.length){
            //两个归并段都有数据
            while (start1<=end1 && start2<=end2){
                //比较
                if(array[start1] <= array[start2]){
                    tmpArray[i++]=array[start1++];
                } else {
                    tmpArray[i++]=array[start2++];
                }
            }
            while (start1<=end1){
                tmpArray[i++]=array[start1++];
            }
            while (start2<=end2){
                tmpArray[i++]=array[start2++];
            }
            //证明一次二路归并已经完成
            start1=end2+1;
            end1=start1+gap-1;
            start2=end1+1;
            end2=start2+gap-1<=array.length-1 ?
                    start2+gap-1 : array.length-1;
        }
        while (start1<array.length){
            tmpArray[i++]=array[start1++];
        }
        //拷贝数据到原始数组
        for(int j=0;j<tmpArray.length;j++){
            array[j]=tmpArray[j];
        }
    }

    public static void mergeSort2(int[] array){
        for(int i=1;i<array.length;i*=2){
            merge2(array,i);
        }
    }

8.计数排序:计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。 操作步骤:

  1. 统计相同元素出现次数
  2. 根据统计的结果将序列回收到原来的序列中

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44149554/article/details/94716548