Java——排序

一、冒泡排序

冒泡排序的原理是相邻元素进行比较,如果第一个元素比第二个元素大,那么交换第一个元素和第二个元素;再第二个元素和第三个元素比,如果第二个元素比第三个元素大,那么交换第二个元素和第三个元素;知道比较到最后一个元素,那么这一趟下类,数组中最大元素就在最后一个。再进行第二趟比较,方式和上面一样只是不用再比较最后一个元素了,因为第一趟最后一个元素就是最大的了。通过循环进行这样的比较直到没有元素需要比较了。

//交换函数
class Swap{
    public static void swap(int[] a,int i,int j){
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}
/**
 * 冒泡排序
 */
class Bubble_Sort{
    public static void bubbleSort(int[] a){
        for(int i = 0;i<a.length;i++){
            for(int j = 0;j<a.length-1-i;j++){
                if(a[j] > a[j+1]){
                    Swap.swap(a, j, j+1);
                }
            }
        }
        System.out.print("冒泡排序:");
        for (int var : a) {
            System.out.print(var+",");
        }
    }
}
class Test{
    public static void main(String[] args) {
        int[] data = new int[]{5,6,1,3,7,8,4,2,0,9};
        Bubble_Sort.bubbleSort(data);
    }
}

二、定向冒泡排序(鸡尾酒排序)

定向冒泡排序是冒泡排序的改进,在冒泡排序的一趟比较中,我们不仅要把最大元素放到了最后面,还要将最小元素放到最左面,这就是定向冒泡排序的思想。我们可以定义2个变量left和right来记录未排好序的元素起始和末尾位置,一趟比较下来最小元素在左面就让left+1,最大元素在最右面就让right-1,这时我们只需比较left和right之间的元素就可以了。

//交换函数
class Swap{
    public static void swap(int[] a,int i,int j){
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}
/**
 * 鸡尾酒排序
 */
class Cocktail_Sort{
    public static void cocktailSort(int[] a){
        int left =0;
        int right = a.length-1;
        while(left<right){
            for(int j = left;j<right;j++){
                if(a[j] > a[j+1]){
                    Swap.swap(a,j,j+1);
                }
            }
            right--;
            for(int j =right;j>left;j--){
                if(a[j]<a[j-1]){
                    Swap.swap(a,j,j-1);
                }
            }
            left++;
        }
        System.out.println("鸡尾酒排序:");
        for (int var : a) {
            System.out.print(var+",");
        }
    }

}
class Test{
    public static void main(String[] args) {
        int[] data = new int[]{5,6,1,3,7,8,4,2,0,9};
        for (int var : data) {
            System.out.print(var+",");
        }
        Cocktail_Sort.cocktailSort(data);
    }
}

三、选择排序

选择排序的思想是在所有元素中找出最小元素,将最小元素放到第一个位置,再在剩下的元素中找到最小的元素,放在之前找的最小元素的后面,知道找完整个数组。具体实现过程是min记录最小元素的位置,假设未比较的数组中第一个元素就是最小的即min=0,通过循环把所有元素进行比较,如果有一个元素比最小元素要小,那么就把这个元素的位置给min,比较完所有元素就找到了哪个元素最小,如果最小元素不是第一个把最小元素与数组第一个元素交换。再从第二个元素开始进行如上操作,知道把整个数组找完。

//交换函数
class Swap{
    public static void swap(int[] a,int i,int j){
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}
class Selection_Sort{
    public static void selectionSort(int[] a){
        for(int i = 0;i<a.length-1;i++){
            int min = i;
            for(int j =i+1;j<a.length;j++){
                if(a[j]<a[min]){
                    min = j;
                }
            }
            if(min!=i){
                Swap.swap(a,min,i);
            }
        }
        System.out.println("选择排序:");
        for (int var : a) {
            System.out.print(var+",");
        }
    }
}
class Test{
    public static void main(String[] args) {
        int[] data = new int[]{5,6,1,3,7,8,4,2,0,9};
        for (int var : data) {
            System.out.print(var+",");
        }
        Selection_Sort.selectionSort(data);
    }
}

四、选择排序改进

对于选择排序的改进思路和鸡尾酒排序一样,一趟循环直接找出最大和最小的位置,将最大的交换到最后的位置、最小的交换到第一个位置,但是要注意当最大的元素正好在最左面时,交换了最小元素和最左面的元素,这时最大元素的位置已经变了,要注意进行判断。

/**
*选择排序改进
*/
class Selection_Sort_OP{
    public static void selectionSort_op(int[] a){
        int left = 0;
        int right = a.length-1;
        while(left<right){
            int max = right-1;
            int min = left;
            for(int j = left+1;j<=right;j++){
                if(a[j]<a[min]){
                    min = j;
                }
                if(a[j]>a[max]){
                    max = j;
                }
            }
            if(min!=left){
                Swap.swap(a,min,left);
            }
            if( max == left){
                max = min;
            }
            if(max !=right){
                Swap.swap(a,max,right);
            }
            left++;
            right--;
        }
        System.out.println("选择排序OP:");
        for (int var : a) {
            System.out.print(var+",");
        }
    }
}
class Test{
    public static void main(String[] args) {
        int[] data = new int[]{5,6,1,3,7,8,4,2,0,9};
        for (int var : data) {
            System.out.print(var+",");
        }
        System.out.println();
        Selection_Sort_OP.selectionSort_op(data);
    }
}

五、插入排序

插入排序类似我们抓扑克牌,我们假设我们左手的牌是有序的,现在我们又抓了一张牌,我们可以从后向前比较,直到找到一个位置这个位置之前的牌比我刚抓的牌小,这个位置之后的牌比我刚抓的牌大,我们就把抓的牌插入这个位置。实现过程是记录下已经排好序的元素的末尾,用一个变量来记录我们右手抓的牌,从后向前比较,找到位置,然后将这个位置后面的元素都向后移动一位,然后把右手抓的牌放到这个位置。

/**
 * 插入排序
 */
class Insertion_Sort{
    public static void insertionSort(int[] a){
        for(int i = 1;i<a.length;i++){
            int get = a[i];
            int end = i - 1;
            while(end >=0 && get < a[end]){
                a[end+1] = a[end];
                end --;
            }
            a[end+1] = get;
        }
        System.out.println("插入排序:");
        for (int var : a) {
            System.out.print(var+",");
        }
    }
}
class Test{
    public static void main(String[] args) {
        int[] data = new int[]{5,6,1,3,7,8,4,2,0,9};
        for (int var : data) {
            System.out.print(var+",");
        }
        System.out.println();
        Insertion_Sort.insertionSort(data);
        }
}

六、二分插入排序——插入排序的改进

插入排序算法需要从后向前不断比较手里的牌,而二分法是将手里的牌分成2部分,找出中间的牌,如果中间的牌比新抓的牌大,说明我要插入的位置在中间的牌左面,右面的牌就不用进行比较了。如果中间的牌比新抓的牌小,说明要插入的位置在中间的牌右面。选择好一面后,再对这一面进行二分直到找出要插入的位置。

当n较大时,二分插入排序的比较次数比直接插入排序的最差情况好得多,但比直接插入排序的最好情况要差,所当以元素初始序列已经接近升序时,直接插入排序比二分插入排序比较次数少。二分插入排序元素移动次数与直接插入排序相同,依赖于元素初始序列。

/**
 * 二分插入排序
 */
class Insertion_Sort_Dichotomy{
    public static void insertionSort_Dichotomy(int[] a){
        for(int i = 1;i<a.length;i++){
            int get = a[i];
            int left = 0;
            int right = i-1;
            while(left <= right){
                int mid = (left + right)/2;
                if(a[mid]>=get){
                    right = mid - 1;
                }else{
                    left = mid + 1;
                }
            }
            int end = i - 1;    
            while(end>=left){
                a[end+1] = a[end];
                end--;
            }
            a[left] = get;
        }
        System.out.println("二分插入排序:");
        for (int var : a) {
            System.out.print(var+",");
        }
    }
}
class Test{
    public static void main(String[] args) {
        int[] data = new int[]{5,6,1,3,7,8,4,2,0,9};
        for (int var : data) {
            System.out.print(var+",");
        }
            System.out.println();
            Insertion_Sort_Dichotomy.insertionSort_Dichotomy(data);
        }
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值