每天一点小知识,快乐你我他。电力电子人家都开始复习了,我还没预习呢。。。。
上动图:不断的分组,颜色一样的为一组,同组进行插入排序
把两个相同颜色的元素归为一组,然后进行插入排序,小的在前,大的在后面
第一轮使用分组和插入排序后的结果
第二轮把分组的距离缩短一半,再继续进行插入排序,相同颜色为一组
第二轮结果
第三轮跟第一轮做法一样,分组缩短一倍,插入排序,相邻的为一组
结果排好序了
实现步骤:
//第一轮代码(第一版),由这个来改变循环的轮数从而让程序成功
public static <E extends Comparable<E>> void shellSort(E[] data ,int l,int r){
int mid=l+(r-l)/2;
for (int i=0;i<mid;i++){
if (data[i].compareTo(data[mid+i])>0){
swap(data,i,mid+i);
}
}
}
//升级,实现成功,这确实有点难理解 有点小问题
public static <E extends Comparable<E>> void shellSort(E[] data ,int l,int r) {
int mid = l + (r - l) / 2;
//如何变化mid的值来不断的减小分组呢?
for (int j = mid; j >= 1; j /= 2) {
//内层循环不变量 同组的进行插入排序
for (int i = 0; i < j; i++) {
//插入排序 同组之间进行排序
//对data[i,i+j,i+2j,i+3j....] 进行插入排序
for (int k = i + j; k < data.length; k += j) {
E midValue = data[k];//存最小
int m;
for (m = k - 1; m >= 0 && midValue.compareTo(data[m]) < 0; m--) {
data[m + 1] = data[m];
}
data[m + 1] = midValue;
}
}
}
}
public static <E extends Comparable<E>> void shellSort3(E[] data ,int l,int r) {
int mid = l + (r - l) / 2;
//如何变化mid的值来不断的减小分组呢?
for (int j = mid; j >= 1; j /= 2) {
//内层循环不变量 同组的进行插入排序
for (int i = 0; i < j; i++) {
//插入排序 同组之间进行排序 同组之间间隔为j,之前插入排序算法之间间隔为1
//对data[i,i+j,i+2j,i+3j....] 进行插入排序
for (int k = i + j; k < data.length; k += j) {
E midValue = data[k];//存最小
int m;
for (m = k; m-j >= 0 && midValue.compareTo(data[m-j]) < 0; m-=j) {
data[m] = data[m-j];
}
data[m] = midValue;
}
}
}
}
//优化
public static <E extends Comparable<E>> void shellSort4(E[] data ,int l,int r) {
int mid = l + (r - l) / 2;
//如何变化mid的值来不断的减小分组呢?
for (int j = mid; j >= 1; j /= 2) {
//插入排序 同组之间进行排序 同组之间间隔为j,之前插入排序算法之间间隔为1
//对data[i...n) 进行插入排序 数组中每一个元素都顺序遍历,不用隔着分组距离来排序了
for (int k =j; k < data.length; k ++) {
E midValue = data[k];//存最小
int m;
for (m = k; m-j >= 0 && midValue.compareTo(data[m-j]) < 0; m-=j) {
data[m] = data[m-j];
}
data[m] = midValue;
}
}
}
//优化 选择不同的步长序列
public static <E extends Comparable<E>> void shellSort5(E[] data ,int l,int r) {
// int mid = l + (r - l) / 2;
int mid=1;
while(mid<data.length){
mid=3*mid+1;//选择不同的步长序列
}//1,4,13,40....
//如何变化mid的值来不断的减小分组呢?
for (int j = mid; j >= 1; j /= 3) {
//插入排序 同组之间进行排序 同组之间间隔为j,之前插入排序算法之间间隔为1
//对data[i...n) 进行插入排序 数组中每一个元素都顺序遍历,不用隔着分组距离来排序了
for (int k =j; k < data.length; k ++) {
E midValue = data[k];//存最小
int m;
for (m = k; m-j >= 0 && midValue.compareTo(data[m-j]) < 0; m-=j) {
data[m] = data[m-j];
}
data[m] = midValue;
}
}
}
public static <E extends Comparable<E>> void swap(E[] data,int i,int j){
E temp=data[i];
data[i]=data[j];
data[j]=temp;
}
public static void main(String[] argc){
Integer[] data={3,2,8,4,6,1,5,7};
shellSort(data,0,data.length);
for (int i=0;i<data.length;i++) {
System.out.print(" " + data[i]);
}
}