折半排序,希尔排序

来源:互联网 发布:淘宝兼职刷信誉平台 编辑:程序博客网 时间:2024/06/05 15:43
package 第十章_内部排序;


public class 折半插入排序 {


public static void main(String[] args) {
// TODO Auto-generated method stub
int a[] = {100,32,62,42,782,3432,322,62,82,92,22};
int dlta [] ={5,3,1};
ShellSort(a,dlta);
binaryInsertSort2(a);
for(int i:a)
System.out.print(i+"\t");
}

//折半插入排序
//折半插入排序和直接插入排序有点不同,直接插入排序直接从按第一个数位有序的从第2个数开始赋值给key并且从i-1位开始依次向前遍历当找到(j>0 && args[j] > key)时,此时要把j到i-1依次向后移动
//因为i位上的数已经被保存在key中,所以不存在被覆盖的情况
//而折半插入排序的过程是从第二位开始
//**************************************************************************
public static void binaryInsertSort2(int[] data) {  
        for (int i = 1; i < data.length; i++) {  
            if (data[i] < data[i - 1]) {  
                // 缓存i处的元素值  
                int tmp = data[i];  
                // 记录搜索范围的左边界  
                int low = 0;  
                // 记录搜索范围的右边界  
                int high = i - 1;  
                while (low <= high) {  
                    // 记录中间位置  
                    int mid = (low + high) / 2;  
                    // 比较中间位置数据和i处数据大小,以缩小搜索范围  
                    if (data[mid] < tmp) {  
                        low = mid + 1;  
                    } else {  
                        high = mid - 1;  
                    }  
                }  
                //将low~i处数据整体向后移动1位  
                for (int j = i; j > low; j--) {  
                    data[j] = data[j - 1];  
                }  
                data[low] = tmp;  
            }  
        }  
    }
//**************************************************************************
//希尔排序
//希尔排序的思想:
/**
* 希尔排序实在插入排序的基础上进行的改进优化,因为插入排序在数量级比较小的情况下具有较好的效率,同时插入排序的实现也比较哦啊简单,所以希尔排序综合这两种情况,进行了
*思路:确定步长,可以通过一个二维数组将步长存储下来
*      通过步长交换数字,循环次数时存储二维数组的长度
*其实shell排序在与直接插入排序是差不多的,知识shell排序在每次的比较从相邻两个之间的比较直接跳转到相隔step个元素
*其中while(j>=0 && key < args[j])
*{
* args[j+step] = args[j];
* j-= step;
*}
*和while(j>=0 && key < args[j])
*{
* args[j+1] = args[j];
* j--;
*}
*完全相似,只是在step = 1 时参数完全一样
*/
//**************************************************************************
/**

* @param arr 用于排序的数组
* @param stepLength 步长 ,即增量序列
* 希尔排序应为跨幅比较大,所以也是不稳定排序
*/
public static void shellInsert(int arr[],int stepLength){
/**
* i = stepLength 在循环开始时,将i的位置直到合适的位置,此时与arr[i]作比较的另一个数组元素的下标便是arr[i - stepLength]
* 例如如下序列:
* 49 38 65 97 76 13 27 49 55 04 假设步长为5,那么此时arr[i] = 13 那么另一个55值便是arr[i - stepLength] = arr[0]=49
*/
for(int i= stepLength;i<arr.length;i++)
{
if(arr[i] < arr[i-stepLength])//13 < 49 
{
int key = arr[i];//key = 1356555
int j = i - stepLength;//j = 5 - 5 = 0
while(j >= 0 && key < arr[j])//arr[j] = arr[0] = 49 
{
arr[j+stepLength] = arr[j]; //arr[j+stepLength] = arr[0+5]= key = 13
j -= stepLength;//j=-5
}
  arr[j+stepLength] = key; 
}
}
}
public static void shell(int args[],int step)
{
for(int i=0;i<args.length;i++)
{
if(args[i] < args[i+step])
{
int key = args[i];
int j = i - step;
while(j>= 0 && key < args[j])
{
j -= step;
}
args[j+step] = key;
}

}
}
public static void ShellSort(int [] arr,int dlta[])
{
//按增量序列dlta[0 .... t-1]对顺序表进行希尔排序
for(int k = 0;k < dlta.length;k++)//步长所组成的二维数组将作为循环的次数
{
shellInsert(arr,dlta[k]);//将步长传入到进行计算
}
}
}





























0 0
原创粉丝点击