java复习基础(6)

来源:互联网 发布:mac vm centos 桥接 编辑:程序博客网 时间:2024/06/07 16:39

对于排序算法,这是个永恒的话题,今天就对常用排序算法进行分析与理解

http://www.cricode.com/3212.html  这个的资源比较生动、形象

假设数据源是int数组

1:插入排序

      插入排序的思想很简单,就是从一个数组的第二项起,进行和已经排好序的序列的元素进行比较,将这个元素插入到子序列中

      java实现:

     public static void insertSort(int[] array) {
        for(int row=1;row<array.length;row++){
            for(int col=0;col<row;col++){
                if(array[row]<=array[col]){    //小于某个值   则需要在col的位置放置array【row】 row到col的需要往后移动
                    int rowCopy=row;           //记录当前row的位置
                    int number=array[row];     //记录要放在col的元素
                    while(row>col){            //将col到row之间的元素想后移动一位
                        array[row]=array[row-1];
                        row--;
                    }
                    array[col]=number;          //放在正确的位置
                    row=rowCopy;                //将row循环继续
                }
            }
//            System.out.println();
//            printArray(array);
        }
    }

2:希尔排序(Shell Sort)是插入排序的一种。是针对直接插入排序算法的改进。该方法又称缩小增量排序,其实希尔排序是在直接插入排序的以下两条性质来改善的

      1)对于已经排好序的序列使用插入排序 效率是很高的  可以不用移动  几乎是线性的效率

      2)直接插入排序每次只能移动一次,对于一些相隔较大的这是很浪费的,所以希尔排序通过缩小增量来让一些间隔大的每步走更远

      java实现:

      public static void hillSorting(int[] array) {
        int padding=array.length;
        do{
            padding =Math.round(padding/2);    
            for(int row=0;row<padding;row++){    //循环padding次   因为分了padding个虚拟数组
                for(int col=row+padding;col<array.length;col=col+padding){    //对数组中的元素进行插入排序  
                    for(int thirdCol=row;thirdCol<col;thirdCol=thirdCol+padding){
                        if(array[col]<=array[thirdCol]){
                            int colCopy=col;
                            int number=array[col];
                            while(colCopy>thirdCol){
                                array[colCopy]=array[colCopy-padding];
                                colCopy=colCopy-padding;
                            }
                            array[thirdCol]=number;
                        }
                    }
                }
            }
        }while(padding>=1);
    }


3:选择排序,就是从序列中找到最大或者最小的,放在第一个或者最后

      java实现:

      public static void selectSort(int[] array) {
        for(int row=0;row<array.length;row++){
            int min=array[row];
            int minIndex=row;
            for(int col=row;col<array.length-1;col++){
                if(array[col]<min){
                    min=array[col];
                    minIndex=col;
                }
            }
            if(minIndex!=row){
                array[minIndex]=array[row];
                array[row]=min;
            }
        }
    }


4:堆排序,

      简单排序算法是通过比较,确定最值的位置。假设未排序元素个数为N,则遍历一趟,需比较N-1次,再遍历下一趟时,需比较N-2次。但是,第二趟比较完全是独立的,没有  利用第一次比较的信息。因为,第一趟比较时也没有把比较信息保留下来。能不能找到一种方法,可以将本趟比较信息记录下来,以供下一趟求最值时使用,从而达到减少比较次数的目的。

      java实现:

public class HeapSort {

    public static void main(String[] args) {
        int[] array = { 6, 3, 6, 1, 8, 7, 5, 4 };
        buildHeap(array);
        handleSort(array);
        System.out.print("排序后的数组:");
        printArray(array);
    }

    public static void handleSort(int[] array) {
        for (int i = array.length; i > 1; i--) {   //从array。length依次减一  知道最后一个
            int temp = array[0];
            array[0] = array[i - 1];
            array[i - 1] = temp;
            handleNode(array, 0, i - 1);        //从0到数组的最后进行每棵树的再次构建
        }
    }

    public static void buildHeap(int[] array) {
        int index = array.length / 2 - 1; // 找到非子叶点 下标
        for (; index >= 0; index--) {        //比较每棵树
            handleNode(array, index, array.length);
        }
    }

    public static void handleNode(int[] array, int index, int length) {
        int rightIndex = 2 * index + 1;
        int leftIndex = 2 * (index + 1);
        int minestIndex = index;
        int temp = array[index];
        if (leftIndex < length && array[minestIndex] > array[leftIndex]) { // 大于左子节点
            minestIndex = leftIndex;
        }
        if (rightIndex < length && array[minestIndex] > array[rightIndex]) { // 大于左子节点
            minestIndex = rightIndex;
        }
        if (minestIndex != index) {    //如果最小值不是父节点  则需要切换
            array[index] = array[minestIndex];
            array[minestIndex] = temp;
            handleNode(array, minestIndex, length);     //切换之后要修改minestIndex为父节点的树
        }
    }

    public static void printArray(int[] array) {
        for (int row = 0; row < array.length; row++) {
            System.out.print(array[row] + "  ");
        }
    }
}

5:冒泡排序

      冒泡的思想就是从第一个数起  和下一个进行比较  如果下一个小于第一个,则把大的那个往后排冒泡,这样下来一趟 则最大值在最后  其实和选择排序有点像   只不过这个是交换

     http://blog.csdn.net/tjunxin/article/details/8711389

     public class BubbleSort {
    public static void main(String[] args) {
        int[] array={6,3,6,1,8,7,5,4};
        bubbleSort(array);
        System.out.print("排序后的数组:");
        printArray(array);
    }
    
    public static void bubbleSort(int[] array) {
        int lastSwapIndex=0;
        for(int row=0;row<array.length;row++){
            lastSwapIndex=array.length-row-1;
            for(int col=0;col<lastSwapIndex;col++){
                if(array[col]>array[col+1]){
                    int temp=array[col];
                    array[col]=array[col+1];
                    array[col+1]=temp;
                    lastSwapIndex=col;     //最一次冒泡中 最后一次切换的位置   表示后面都是正常顺序
                }
            }
        }
    }
    
    public static void printArray(int[] array){
        for(int row=0;row<array.length;row++){
            System.out.print(array[row]+"  ");
        }
    }
}

6:快速排序

      快速排序是在冒泡排序的基础上进行改进的,简单来说,快速排序的算法思路就是将数组分为两个部分,对每个部分进行排序,而中间的数大于前面的数组额小于或等于后面的数组

      java实现:

    package com.cqut.sort;

public class Quicksort {
    public static void main(String[] args) {
        int[] array={6,3,6,1,8,7,5,4};
        quicksort(array);
        System.out.print("排序后的数组:");
        printArray(array);
    }
    
    public static void quicksort(int[] array) {
        quicksortEachStep(array,0,array.length-1);
        //4 3 6 1 8 7 5
    }
    
    public static void quicksortEachStep(int[] array,int low,int high) {
        if(high>low){
            int key=array[low];
            int left=low;
            int right=high;
            while(left<right){
                while(right>left&&array[right]>=key){
                    right--;
                }
                if (left<right) {
                    array[left++]=array[right];
                }
                //array[low]=array[right];
                while(right>left&&array[left]<key){
                    left++;
                }
                if(left<right){
                    array[right--]=array[left];
                }
                //array[high]=array[left];
                array[left]=key;
            }
            quicksortEachStep(array,low,left-1);
            quicksortEachStep(array,left+1,high);
        }
    }
    
    public static void printArray(int[] array){
        for(int row=0;row<array.length;row++){
            System.out.print(array[row]+"  ");
        }
    }
}

7:归并排序

      归并排序的思想就是采用分治法  将左右排序然后进行集合  左右排序又再次左右排序  知道每个数组只有一个元素   这时候的数组是有序的(只有一个元素)  然后将两个排好序的元素数组进行集合  这样就达到目的

   package com.cqut.sort;

public class MergeSort {

    public static void main(String[] args) {
        int[] array = { 6, 3, 5, 1, 8, 7, 5, 4 };
        mergeSort(array);
        System.out.print("排序后的数组:");
        printArray(array);
    }

    public static void mergeSort(int[] array) {
        int[] temp=new int[array.length];
        splitArray(array,0,array.length-1,temp);
    }
    
    public static void splitArray(int[] array,int first,int last,int[] temp){
        if(first<last){
            int mid=(first+last)/2;
            splitArray(array,first,mid,temp);
            splitArray(array,mid+1,last,temp);
            mergeArray(array,mid,first,last,temp);
        }
    }
    
    
    public static void mergeArray(int[] array,int midIndex,int beginIndex,int lastIndex,int[] temp){
        int i=beginIndex;
        int j=midIndex+1;
        int k=0;
        while(i<=midIndex && j<=lastIndex){
            if(array[i]<array[j]){
                temp[k++]=array[i++];
            }
            else{
                temp[k++]=array[j++];
            }
        }
        while (i  <=midIndex)  
            temp[k++]=array[i++];  
          
        while (j <=lastIndex)  
            temp[k++]=array[j++];  
        
        for(int row=0;row<k;row++){
            array[beginIndex+row]=temp[row];
        }
    }

    public static void printArray(int[] array) {
        for (int row = 0; row < array.length; row++) {
            System.out.print(array[row] + "  ");
        }
    }
}

8:基数排序

     基数排序也是桶排序   将数按照个位数  十位数  百位数  进行放入桶中

   package com.cqut.sort;

public class RadixSort {

    public static void main(String[] args) {
        int[] array = { 6, 3, 5, 1, 8, 7, 5, 4 };
        radixSort(array, 1);
        System.out.print("排序后的数组:");
        printArray(array);
    }

    public static void radixSort(int[] array, int n) {
        int k = 0;
        boolean needFlop = false; // 需要继续循环
        int[][] radis = new int[10][array.length];
        int[] order = new int[10];
        for (int i = 0; i < array.length; i++) {
            int x = (int) Math.pow(10, n);
            int num = array[i] % x / (x / 10);
            if (num != 0 && !needFlop) {
                needFlop = true;
            }
            order[num]++;
            radis[num][order[num] - 1] = array[i];
        }
        for (int i = 0; i < order.length; i++) {
            if (order[i] != 0) { // 即桶中有数据
                for (int j = 0; j < order[i]; j++) {
                    array[k++] = radis[i][j];
                }
            }
        }

        if (needFlop) {
            n++;
            radixSort(array, n);
        } else {
            return;
        }
    }

    public static void printArray(int[] array) {
        for (int row = 0; row < array.length; row++) {
            System.out.print(array[row] + "  ");
        }
    }
}


0 0
原创粉丝点击