简单的排序--冒泡、选择、插入、希尔、快排

 

 

1、冒泡排序时间复杂度O(n^2)

 冒泡排序算法,比较相邻的两个数,否者比前者大,则交换。整个过程从开始的第一对到最后的一对。这步完成后最后的元素会是最大的,在对剩下的数进行比较交换,直到没有一对数字需要比较。 

public class BubbleSort {
    public static void bubblesort(long[] arr){
        long tmp = 0;
        for (int i = 0; i < arr.length -1 ; i++) {
            for (int j = arr.length -1;j>i;j--){
                if (arr[j] < arr[j-1]){
                    tmp = arr[j];
                    arr[j] = arr[j-1];
                    arr[j-1] = tmp;
                }
            }
        }
    }
}
public static long[] sort(long[] arr){
for (int i = 1; i < arr.length;i++) {//冒泡次数n-1
for (int j = 0;j < arr.length-1;j++){
if (arr[j] > arr[j + 1]){
long tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
return arr;
}
 

 

2、选择排序O(n^2)

选择第一个数据作为最小值,依次与后面的数进行比较,找到比之更小的数,最后交换。

public class SelectionSort {
    public static void sort(long[] arr){
        int k = 0;
        long tmp = 0;
        for (int i = 0; i < arr.length -1 ; i++) {//n -1 次比较
            k = i;
            for(int j = i;j < arr.length;j++){
                if(arr[j] < arr[k]){
                    k = j;
                }
            }
            tmp = arr[i];
            arr[i] = arr[k];
            arr[k] = tmp;
        }
    }
}

public static long[] sort2(long[] arr){
for (int i = 0; i < arr.length -1;i++) {//n-1轮比较
int min = i;//选择第一个数最小
for (int j = i + 1;j < arr.length;j++){
if (arr[min] > arr[j]){
min = j;
}
}
if (i != min){
long tmp = arr[i];
arr[i] = arr[min];
arr[min] = tmp;
}
}
return arr;
}
 

3、插入排序 最有O(n)  最坏O(n^2)

插入排序类是斗地主时马牌,把一张牌插入到适合它的位置上。

public class InsertSort {
    public static void sort(long[] arr) {
        long tmp = 0;

        for(int i = 1; i < arr.length; i++) {
            tmp = arr[i];
            int j = i;
            while(j > 0 && arr[j -1] >= tmp) {
                arr[j] = arr[j - 1];
                j--;
            }
            arr[j] = tmp;
        }
    }
}

 4、希尔排序

主要先寻找最大间隔,然后两两比较交换,当间隔为1时,就相当于插入排序。

public static void sort(long[] arr){
        //初始化间隔
        int h = 1;
        //计算最大间隔,最大间隔不大于数组的长度
        while (h < arr.length / 3){
            h = h * 3 + 1;
        }
        System.out.println(h);
        while (h > 0){
            //进行插入排序
            long tmp = 0;
            for (int i = h;i < arr.length;i++){
                tmp = arr[i];
                int j = i;
                while (j > h -1 && arr[j-h] >= tmp){
                    arr[j] = arr[j - h];
                    j -= h;
                }
                arr[j] = tmp;
            }
            // 减小间隔
            h = (h - 1)/3;
        }
    }

 

5、归并排序

 

 

       //两路归并算法,两个排好序的子序列合并为一个子序列
        public static void merge(int[] a, int left, int mid, int right){
            int []tmp=new int[a.length];//辅助数组
            int p1=left,p2=mid+1,k=left;//p1、p2是检测指针,k是存放指针

            while(p1<=mid && p2<=right){
                if(a[p1]<=a[p2])
                    tmp[k++]=a[p1++];
                else
                    tmp[k++]=a[p2++];
            }

            while(p1<=mid) tmp[k++]=a[p1++];//如果第一个序列未检测完,直接将后面所有元素加到合并的序列中
            while(p2<=right) tmp[k++]=a[p2++];//同上

            //复制回原素组
            for (int i = left; i <=right; i++)
                a[i]=tmp[i];
        }

        public static void mergeSort(int [] a,int start,int end){
            if(start<end){//当子序列中只有一个元素时结束递归
                int mid=(start+end)/2;//划分子序列
                mergeSort(a, start, mid);//对左侧子序列进行递归排序
                mergeSort(a, mid+1, end);//对右侧子序列进行递归排序
                merge(a, start, mid, end);//合并
            }
        }

 

6、快排

先假定一个关键字,找到插入点,在左右递归排序。

//划分数组
    public static int partition(long arr[],int left,int right,long point){
        int leftptr = left - 1;
        int rightptr = right;
        while (true){
            //循环,将比关键字小的留在左端
            while (leftptr < rightptr && arr[++leftptr] < point);
            //循环,将比关键字大的留在右端
            while (rightptr > leftptr && arr[--rightptr] > point);
            if (leftptr >= rightptr){
                break;
            }else {
                //将比关键字大的移动到右端,小的移动到左端
                long tmp = arr[leftptr];
                arr[leftptr] = arr[rightptr];
                arr[rightptr] = tmp;
            }
        }
        //最后,
        long tmp = arr[leftptr];
        arr[leftptr] = arr[right];
        arr[right] = tmp;
        return leftptr;
    }
    public static void sort(long[] arr,int left,int right){
        if (right - left <= 0){
            return;
        }else {
            //设置关键字
            long point = arr[right];//采用最右端作为关键字
            //获取切入点,并进行排序
            int partition = partition(arr,left,right,point);
            sort(arr,left, partition-1);
            sort(arr, partition+1,right);
        }
    }

 

posted @ 2020-04-21 15:31  也许明天、  阅读(207)  评论(0)    收藏  举报