归并排序,插入排序,快速排序,冒泡排序,选择排序的思想

简单的梳理一下我对几种简单算法的思想的认识,代码我都是copy的,网上有很多前辈的代码是不错的。我这里就不去再次实现了,虽然之前基本都写过。

一.归并排序:
先递归:
一个数组,可以看做是由两个子数组构成的,而这两个数组,也可以当成是由两个子数组构成的。。。。不断直到当这个数组中只有一个元素的时候(起始位置的下标和终止位置的下标相等)。
再合并:
先申请一块数组存放这两个数组的值,排序完成然后存回原数组对应的位置。
当两个数组中有其中一个已经全部放入temp数组的时候,就将另一个数组的直接放入最后就好。
时间复杂度:O(n log n)

归并排序是基于分治法的
分治法的一般的求解步骤为:
a 分解:将原问题分解为一系列子问题
b 解决:递归地求解各子问题
c 合并:将子问题的结果合并为原问题的解
注:代码是copy的

package com.collonn.algorithm.sort;  

/** 
 * <pre> 
 * 经典归并排序 
 * </pre> 
 */  
public class MergeSort {  

    public void mergeSort(int[] s, int start, int end) {  
        if (start >= end) {  
            return;  
        }  

        int m = (start + end) / 2;  
        int start1 = start;  
        int end1 = m;  
        int start2 = m + 1;  
        int end2 = end;  
        this.mergeSort(s, start1, end1);  
        this.mergeSort(s, start2, end2);  

        this.merge(s, start1, end1, start2, end2);  
    }  

    // 合并两个有序数组为一个有序数组  
    private void merge(int[] s, int start1, int end1, int start2, int end2) {  
        System.out.printf("\n开始合并,合并范围,[%d,%d],[%d,%d]", start1, end1, start2, end2);  
        int start = start1;  
        // 临时数组  
        int[] t = new int[end2 - start1 + 1];  
        // 临时数组下标  
        int i = 0;  

        // 比较开始  
        while (start1 <= end1 && start2 <= end2) {  
            if (s[start1] < s[start2]) {  
                t[i] = s[start1];  
                start1++;  
                i++;  
                continue;  
            }  
            if (s[start1] > s[start2]) {  
                t[i] = s[start2];  
                start2++;  
                i++;  
                continue;  
            }  
        }  

        // 拷贝剩余元素  
        while (start1 <= end1) {  
            t[i] = s[start1];  
            start1++;  
            i++;  
        }  

        // 拷贝剩余元素  
        while (start2 <= end2) {  
            t[i] = s[start2];  
            start2++;  
            i++;  
        }  

        // 将已排好序的元素放回对应位置  
        for (i = 0; i < t.length; i++) {  
            s[start + i] = t[i];  
        }  

        // 打印数组  
        PrintArray(s);  
    }  

    // 打印数组  
    private static void PrintArray(int[] s) {  
        System.out.print("\n下标:");  
        for (int p = 0; p < s.length; p++) {  
            System.out.printf("%2d,", p);  
        }  
        System.out.print("\n值值:");  
        for (Integer m : s) {  
            System.out.printf("%2d,", m);  
        }  
        System.out.print("\n-----------------------------");  
    }  

    public static void main(String[] args) {  
        // int[] s = new int[] { 99, 88, 5, 99, 7, 9, 3, 8, 10, 90, 56, 83, 39, 22 };  
        int[] s = new int[] { 9, 2, 3, 7, 6, 5, 8, };  

        // 打印数组  
        PrintArray(s);  

        MergeSort mergeSort = new MergeSort();  
        mergeSort.mergeSort(s, 0, s.length - 1);  

        // 打印数组  
        PrintArray(s);  
    }  

}  

二.插入排序:
插入排序是这样的:一个数组a,从第一个元素开始,认为其是一个子数组b(其实可以不存在),那么子数组b是有序的。开始遍历整个数组b,将从第二个数开始的元素,插入到数组b中的相应的位置。
时间复杂度 O(n2)

 package com.njue;  

public class insertSort {  
public insertSort(){  
    inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};  
    int temp=0;  
    for(int i=1;i<a.length;i++){  
       int j=i-1;  
       temp=a[i];  
       for(;j>=0&&temp<a[j];j--){  
       a[j+1]=a[j];                       //将大于temp的值整体后移一个单位  
       }  
       a[j+1]=temp;  
    }  
    for(int i=0;i<a.length;i++)  
       System.out.println(a[i]);  
}  
}

三.快速排序
快排算是用的很多的一种排序了,其的思想是,有一个准线temp(一般默认第一个),从左右两边同时开始,左边找到比temp大于等于的第一个元素,右边找到比temp小于等于的第一个元素,两两交换。直到两个下标元素相碰为止,然后开始递归。将两个子数组递归下去就ok。

public class quickSort {  
  int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};  
public  quickSort(){  
    quick(a);  
    for(int i=0;i<a.length;i++)  
        System.out.println(a[i]);  
}  
public int getMiddle(int[] list, int low, int high) {     
            int tmp = list[low];    //数组的第一个作为中轴     
            while (low < high) {     
                while (low < high && list[high] >= tmp) {     

      high--;     
                }     
                list[low] = list[high];   //比中轴小的记录移到低端     
                while (low < high && list[low] <= tmp) {     
                    low++;     
                }     
                list[high] = list[low];   //比中轴大的记录移到高端     
            }     
           list[low] = tmp;              //中轴记录到尾     
            return low;                   //返回中轴的位置     
        }    
public void _quickSort(int[] list, int low, int high) {     
            if (low < high) {     
               int middle = getMiddle(list, low, high);  //将list数组进行一分为二     
                _quickSort(list, low, middle - 1);        //对低字表进行递归排序     
               _quickSort(list, middle + 1, high);       //对高字表进行递归排序     
            }     
        }   
public void quick(int[] a2) {     
            if (a2.length > 0) {    //查看数组是否为空     
                _quickSort(a2, 0, a2.length - 1);     
        }     
       }   
}

四.冒泡排序:
很经典的排序了。从第一个元素i开始,之后的元素两两比较,大的浮在后边,那么一次交换之后,最大的数就在最右了。第二次,仍然从第一个数开始,到倒数第二个数停止,两两比较,大的浮在最右边,那么次大数就在倒数第二个位置了。。。。
时间复杂度:O(n2)

public class bubbleSort {  
public  bubbleSort(){  
     int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};  
    int temp=0;  
    for(int i=0;i<a.length-1;i++){  
        for(int j=0;j<a.length-1-i;j++){  
        if(a[j]>a[j+1]){  
            temp=a[j];  
            a[j]=a[j+1];  
            a[j+1]=temp;  
        }  
        }  
    }  
    for(int i=0;i<a.length;i++)  
    System.out.println(a[i]);     
}  
}

五.选择排序:
在一个数组中,找出最小的元素,然后和第一个元素交换。然后再选出次小的元素,和第二个元素交换。。。。。。
时间复杂度:O(n2)

public class selectSort {  
    public selectSort(){  
        int a[]={1,54,6,3,78,34,12,45};  
        int position=0;  
        for(int i=0;i<a.length;i++){  

            int j=i+1;  
            position=i;  
            int temp=a[i];  
            for(;j<a.length;j++){  
            if(a[j]<temp){  
                temp=a[j];  
                position=j;  
            }  
            }  
            a[position]=a[i];  
            a[i]=temp;  
        }  
        for(int i=0;i<a.length;i++)  
            System.out.println(a[i]);  
    }  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值