排序

public class Sort {
    /**
     * @param data
     * 冒泡排序  比较接近选择排序,不同的是冒泡排序一直在交换,而选择排序是不断比较,
     * 直到确定正确的下标一次交换完成
     */
    public void bubble_sort(int[] data) {
        int temp;
        for(int i=0; i<data.length; i++){
            //内层循环从后向前,找到最小值.循环终止时,最小值处于i位置
            for (int j=data.length-1; j>i; j--){
                if(data[j]<data[j-1]){
                    temp = data[j-1];
                    data[j-1] = data[j];
                    data[j] = temp;
                }
            }
        }        
    }
    

    
    /**
     * 插入排序  固定元素找位置
     * @param data 手中有data.length张牌,从第二张牌开始直到最后一张牌
     * 插入前面已经排好序的牌中,程序中的j起到遍历之前已排好序的牌的作用
     */
    public void insert_sort(int[] data) {
        int key,j;
        for(int i=1; i<data.length; i++){
            key = data[i];
            j= i-1;
            //key相当于data[j+1],因为0~j数据都是有序的,key只要比j大
            //则比0~j都要大
            while(j>=0 && key<data[j]){
                data[j+1] = data[j];//可以理解为元素向后移动
                j--;
            }            
            data[j+1] = key;
        }    
    }

    
    /**
     * 选择排序 固定位置找元素
     * @param data
     */
    public void selection_sort(int[] data) {
        int smallest,temp;
        for(int i=0; i<data.length-1; i++){
            smallest = i;
            for(int j=i+1; j<data.length; j++){
                if(data[j] < data[smallest]){
                    smallest = j;
                }
            }
            
            temp = data[i];
            data[i] = data[smallest];
            data[smallest] = temp;
        }        
    }
    
    
    /**归并排序
     * @param data
     */
    public void  merge_sort(int[] data){
        merge_sort(data, 0, data.length-1);
    }    
    private void merge_sort(int[] data, int p, int r) {
        //这段代码可这样理解:
        //一个大数组传入,被分成两半,两半数组分别传入
        //再又被分成两半,直到每一半只有一个元素
        //然后开始合并        
        if(p<r){
            int q = (p+r)/2;
            merge_sort(data,p,q);
            merge_sort(data,q+1,r);
            merge(data,p,q,r);
        }
    }
    private void merge(int[] data, int p, int q, int r) {
        
        //新建数组L,R
        //L保存原数组p~q元素
        //R保存原数组q+1~r元素
        int L[] = new int[q-p+1];
        int R[] = new int[r-q];
        System.arraycopy(data, p, L, 0, L.length);
        System.arraycopy(data, q+1, R, 0, R.length);
        
        //变量k的作用在于将原数组p~r位置的元素按从小到大顺序重排
        //i,j分别用来遍历左右数组
        int i=0;
        int j=0;
        int k;
        for(k=p; k<=r; k++){
            if(L[i]<=R[j]){
                data[k] = L[i];
                i++;
                //数组到头,循环结束
                if(i==L.length){
                   break;
                }
            }else{
                data[k] = R[j];
                j++;
                if(j==R.length){
                    break;
                }
            }
        }
        //当某个数组遍历完,考虑到两个子数组都是有序的
        //只需要将另外一个数组的剩余值全部复制到原数组
        //上面循环退出时,k位置已经被赋值,所以是++k
        //另一个数组的赋值却未能执行,所以是i(j)++
        while(i<L.length){
            data[++k] = L[i++];
        }
        while(j<R.length){
            data[++k] = R[j++];
        }
        
    }


    
    /**
     * 快速排序
     * @param data
     */
    public void quick_sort(int[] data){
        quick_sort(data, 0, data.length-1);
    }
    private void quick_sort(int[] a, int p, int r){
        if(p < r){
            int q = partition(a, p, r);
            quick_sort(a,p,q-1);
            quick_sort(a,q+1,r);
        }        
    }
    /**
     * @return  
     */
    private int partition(int[] a, int p, int r){
        int i = p-1;
        int x= a[r];
        int temp;
        //选最后一个数字作为比较对象,方便for循环书写,中间没有被隔断
        for (int j = p ; j<r; j++){
            if(a[j] <= x){
                i = i+1;
                temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
        }
        temp = a[i+1];
        a[i+1] = a[r];
        a[r]  = temp;
        return i+1;
        //j用来遍历数组,i用来标记将要发生交换的位置
    }
    

}

 

posted @ 2015-09-05 18:44  疾风剑  阅读(208)  评论(0)    收藏  举报