常见排序方法整理

/**
建立一个用于操作数组的工具类,其中包含着常见的对数组的操作函数如:排序,最值等

@author jepson
@version v1.0
*/


public class ArrayTool
{
    /*该类中的方法都是静态的,所以该类是不需要创建对象的,
      为了保证不让其它程序创建该类对象
      可以将该类的构造函数私有化。
    */
    
    
    private ArrayTool(){}   
                            
               
    /**
     对给定的整数数组进行直接插入排序
     @param arr 接收一个元素类型为int的整数数组
    */
    
    public static void directInsertSort(int[] arr)   //直接插入排序
    {
        for (int i=1; i<arr.length; ++i)      //第一个元素已经有序,所以从第二个元素开始
        {
            int temp = arr[i];                //将要插入的元素暂存于temp临时变量中
            int j = i-1;                      //j指向想要与待插入元素进行比较的第一个元素,也就是它左边的第一个元素
            while (j>=0&&temp<arr[j])           //如果j>=0并且带插入元素比当前比较的元素小,就让该元素后移一位。
            {
                arr[j+1]=arr[j];                  //后移一位
                --j;                          //j指向下一个需要比较的元素。
            }
            arr[j+1]=temp;                      //找到了插入位置之后,将待插入元素放入其中。 
        }
    }


    /**
    对给定的整数数组进行折半插入排序
    @param arr 接收一个元素类型为int型的整数数组
    */

    public static void binaryInsertSort(int[] arr)   //折半插入排序
    {
        for (int i=1; i<arr.length; ++i)             //第一个元素已经有序,所以从第二个元素开始
        {
            int temp = arr[i];                       //将要插入的元素暂存于temp临时变量中
            int low = 0;                             //low指向待查找的有序序列的第一个元素的下标
            int high = i-1;                          //high指向待查找的有序序列的最后一个元素的角标
            while (low<=high)                        //low>high结束运行
            {
                int mid = (low+high)/2;              //mid指向中间位置。
                if (temp<arr[mid])                   //如果待插入元素小于中间位置的元素,那么就应该在左侧查找。
                {
                    high = mid-1;
                }
                else                                 //如果待插入元素不小于中间位置的元素,那么就应该在右侧查找。
                {
                    low = mid +1;
                }
            }//while循环结束就表示找到了插入位置
            for (int j=i-1;j>=low ;--j )             //有序序列包括插入位置在类的元素都应该后移一个位置
            {
                arr[j+1] = arr[j];                   //后移一个位置。
                --j;                                 //j指向下一个要移动的元素
            }
            arr[low]=temp;                           //将待插入元素插入找到的位置。。
            //arr[high+1]=temp;

        }
        
    }

   /**
   对给定的整数数组进行希尔排序
   @param arr  接收一个元素类型为int型的整数数组
   */

   public static void shellSort(int[] arr)       //希尔排序
    {
       for (int gap=arr.length/2;gap>=1 ;gap/=2 )  //设置增量,当增量<1的时候结束
       {
           for (int i=gap;i<arr.length ;++i )      //这里开始实际就是直接插入排序
           {
               int temp = arr[i];
               int j=i-gap;
               while (j>=0&&temp<arr[j])
               {
                   arr[j+gap]=arr[j];
                   j=j-gap;
               }
               arr[j+gap] = temp;
           }
       }
    }

    /**
    对给定的数组进行交换类的冒泡排序
    @param arr 接收一个元素类型为int型的整数数组
    */
    public static void bubbleSort(int[] arr)    //冒泡排序
    {
        for (int i=1;i<arr.length ;++i )       //外层大循环为n-1圈。
        {
            int flag=0;                        //每一次循环的时候让flag=0,冒泡排序结束的条件是一趟排序没有发生交换
            for (int j=0;j<arr.length-i;++j )  //从第一个元素开始让第一个元素和第二元素比较,第二个元素和第三个元素比较
            {
                if (arr[j]>arr[j+1])           //只要前面一个元素大于后面的元素就交换
                {
                    //int temp=arr[j];
                    //arr[j]=arr[j+1];
                    //arr[j+1]=temp;
                    swap(arr,j,j+1);
                    flag=1;                   //发生了交换就置falg=1;
                }
            }
            if (flag==0)                       //如果一趟中没有发生交换,说明就已经有序,结束运行,直接返回给调用函数继续执行
            {
                return;
            }
        }
    }
     /**
    对给定的数组进行交换类的快速排序
    @param arr 接收一个元素类型为int型的整数数组
    @param Left 接收要排序的数据的第一个元素的角标
    @param Right 接收要排序的数据的最后一个元素的角标
    */
    public static void quickSort(int[] arr,int Left,int Right)    //快速排序
    {
        int i=Left;                                                //i指向要排序的数列的最左边元素
        int j=Right;                                               //j指向要排序的数据的最右边元素
        if (Left<Right)                                                   //只要区域元素不少于两个就执行
        {
            int temp=arr[i];                                      //将轴心暂存于temp中。
            while (i!=j)                                         //i=j的时候停止循环
            {
                while (j>i&&arr[j]>temp)                         //从右向左扫描,找到第一个不大于temp的元素结束
                {
                    --j;
                }
                if (j>i)                                         //将这个元素放入i位置,并让i右移一个位置
                {
                    arr[i]=arr[j];
                    ++i;
                }
                while (i<j&&arr[i]<temp)                         //i从左向右扫描,找到第一个不小于temp的元素结束
                {
                    ++i;
                }
                if (i<j)                                        //将这个元素放入ji位置,并让j左移一个位置
                {
                    arr[j]=arr[i];
                    --j;
                }
            }
            arr[i]=temp;                                         //将轴心放入找到的位置。
            quickSort(arr,Left,i-1);                              //递归处理轴心的左侧部分
            quickSort(arr,i+1,Right);                              //递归处理轴心的右侧部分
        }
    }

    /**
     对给定的整数数组进行选择排序
     @param arr 接收一个元素为int型的数组
    */
    public static void selectSort(int[] arr)
    {
        int j,k,temp;
        for (int i=0;i<arr.length ;++i )
        {
            k=i;
            for (j=i; j<arr.length; ++j)
            {
                if (arr[j]<arr[k])
                {
                    k=j;
                }

            }
            //temp = arr[i];
            //arr[i]=arr[k];
            //arr[k]=temp;
            swap(arr,i,k);
        }
    }
    /**
     对给定的整数数组进行堆排序
     @param arr 接收一个元素为int型的数组
    */
    public static void heapSort(int[] arr)
    {
        for (int i=(arr.length-1)/2; i>=0;--i )   //构建初始堆
        {
            sift(arr,i,arr.length-1);
        }
        for (int i=arr.length-1;i>0 ; --i)  //让堆中的第一个元素和最后一个元素交换,并且对交换后的第一个位置的元素进行调整
        {
            //int temp = arr[0];
            //arr[0] = arr[i];
            //arr[i] = arr[0];
            swap(arr,0,i);
            sift(arr,0,i-1);
        }

    }
    private static void sift(int arr[] , int low,int high)  //对low到high位置,low位置进行堆排序
    {
        int i = low;   //i指向要调整的元素
        int j = 2*i+1; //指向左孩子
        int temp = arr[i];
        while (j<=high)  //只要j>high就循环
        {
            if (j<high&&arr[j]<arr[j+1])   //如果有右孩子 有孩子更大,就让j指向更大的孩子
            {
                ++j;
            }
            if (temp<arr[j])     //如果孩子结点更大,就让最大的孩子放到双亲的位置上去。
            {
                arr[i]=arr[j];
                i=j;
                j=2*i+1;
            }
            else 
                break;

        }
        arr[i]=temp;            //将调整的元素放到最值的位置。    
    }
    

    /**
     用于给数组进行元素的位置置换
     @param arr 接收一个元素为int型的数组
     @param a   要交换的元素的下标
     @param b   要交换的元素的下标
     
    */


    private static void swap(int[] arr,int a, int b)
    {
        int temp;
        temp=arr[a];
        arr[a]=arr[b];
        arr[b]=temp;
    }


    /**
     获取整数数组的最大值
     @param arr 接收一个元素为int型的数组
     @return    返回该数组的最大元素值
    */
    public static int getMax(int[] arr)  
    {
        int max = arr[0];
        for (int i=0;i<arr.length ; ++i)
        {
            if (max<arr[i])
            {
                max = arr[i];
            }
        }
        return max;
    }
    /**
     获取整数数组的最小值
     @param arr 接收一个元素为int型的数组
     @return    返回该数组的最大元素值
    */
    public static int getMin(int[] arr)  
    {
        int min = arr[0];
        for (int i=0;i<arr.length ; ++i)
        {
            if (min>arr[i])
            {
                min = arr[i];
            }
        }
        return min;
    }


   /**
     获取指定元素在指定数组中的角标
     @param arr 接收一个元素为int型的数组
     @param key 指定的元素 
     @return 该元素在数组中的坐标
    */
    public static int getIndex(int[] arr,int key)
    {
        for (int i=0;i<arr.length ;++i )
        {
            if (arr[i]==key)
            {
                return i;
            }
        }
        return -1;
    }
    
     /**
     使用二分查找(折半查找)获取指定元素在指定数组中的角标
     @param arr 接收一个元素为int型的数组
     @param key 指定的元素 
     @return 找到了返回该元素在数组中的坐标,没找到返回 “-插入点-1”
    */
    public static int binarySearch(int[] arr,int key)  //二分查找
    {
        int low=0;  //指向查找序列的第一个位置                                    
        int high=arr.length-1;//指向查找序列的最后一个位置
        int mid;
        while (low<=high)   //low>high的时候结束循环
        {
            mid = (low+high)>>1;  //mid指向中间位置
            if (arr[mid]>key)   //终于该查找元素,则在左侧部分查找
            {
                high=mid-1;
            }
            else if (arr[mid]<key)  //小于则在右侧部分查找
            {
                low=mid+1;
            }
            else   //找到了,就返回坐标
                return mid;
        }
        return -low-1;   //没有找到返回 -插入点-1
    }



    


     /**
     将int型数组转换成字符串。格式:[e1,e2,......]
     @param arr 接收一个元素为int型的数组
     @return 返回该数组的字符串表现形式
    */
    public static String arrayToString(int[] arr)
    {
        String str = "[";
        for (int i=0;i<arr.length ;++i )
        {
            if (i!=arr.length-1)
            {
                str = str +arr[i]+"," ;
            }
            else
            {
                str = str + arr[i]+"]";
            }
        }
        return str;
    }
    /**
     将int型数组转换成字符串。格式:[e(n),e(n-1),......,e2,e1]
     @param arr 接收一个元素为int型的数组
     @return 返回该数组的字符串表现形式
    */
    public static String arrayReverseToString(int[] arr)
    {
        String str = "[";
        for (int i=arr.length-1;i>=0 ;--i )
        {
            if (i!=0)
            {
                str = str +arr[i]+"," ;
            }
            else
            {
                str = str + arr[i]+"]";
            }
        }
        return str;
    }
}

 

posted @ 2018-08-10 19:25  Jepson6669  阅读(189)  评论(0编辑  收藏  举报