壳牌排序和混乱与差距

时间:2015-03-24 16:59:45

标签: algorithm sorting shellsort

我最近看到并研究了shell-sort算法,并看到了提供here的示例。在这个例子中,他们认为是'inc'或'gap'。

我做了算法的c实现,并将间隙值作为排序中的参数。

我观察的是10个未分类的值:

  

5,1,3,2,4,8,6,9,7,10

使用任何差距,我得到以下输出:

  

1 2 3 4 5 6 8 7 9 10

我已经构建了一个代码的递归版本,它在这里:

void shellSort(int *arr, int size, int gap){
    int i, tmp;
    if (gap == 0) return;
    for (i = 0; i < size / gap; i+=gap){
        if (i < size - 1){//Valid Index
            if (arr[i] > arr[i + gap]){
                tmp = arr[i];
                arr[i] = arr[i + gap];
                arr[i + gap] = tmp;
            }
        }
    }
    printf("Interation : \n");
    for (i = 0; i < 10; i++){
        printf("%d\t", arr[i]);
    }
    printf("\n\n");
    shellSort(arr, size, gap - 1);
}

示例:

int main()
{
    int arr[] = { 5, 1, 3, 2, 4, 8, 6, 9, 7, 10 }, i;
    shellSort(&arr[0], 10, 3);
    getch();
    return 0;
}

在阅读了互联网上的资料后,我对选择这个差距值感到困惑,在维基百科这样的地方,他们正在使用间隙序列。一些帮助将不胜感激。

更正后,

for (i = 0; i < size - gap; i++)

输出:

  

1 3 2 4 5 6 8 7 9 10

2 个答案:

答案 0 :(得分:1)

  1. 此代码不是shell排序,它是一种comb sort
  2. 在这一行中 for (i = 0; i < size / gap; i+=gap)
    索引我没有遍历整个数组。可能的纠正:
    for (i = 0; i < size - gap; i++)
  3. 对于完全排序,您必须在发生交换时使用gap = 1重复排序。 Examples
  4. 每个关于炮弹或梳子的手册都描述了差距。 简而言之 - 两个由间隙分隔的索引遍历数组,因此无序元素在排序数组中更靠近它们的位置。每次运行间隙减少后(在弹药分母中为2-3,在combsort中为1.3)。将间隙减1(如代码所示)会使代码变慢。

答案 1 :(得分:0)

在Shell-Sort算法中,您需要理解对数组进行间隙排序(或h排序)的概念。

假设你有差距&#39; h。您将从第一个元素tab [0]开始,并在数组中对h间隔的所有元素进行排序:tab [0],tab [h],tab [2h] ...然后您将选择secend元素作为开始并尝试对间隔元素进行排序。每次起始元素递增。要对h间距元素进行排序,请使用插入排序算法。

之后,从最大的差距开始为h插入排序代码选择一个序列。

这是我在java中的实现:

// Using Pratt sequence 
public static void hSort(int tab[]) {
    int N = tab.length;    
    int k = 0;    
    int sequence = 1;

    // Getting the final term of the pratt sequence 
    while(((int)(Math.pow(3, k) - 1) / 2) < N/3) {
        sequence = (int)(Math.pow(3, k) - 1) / 2;
        k++;
    }     
    k--;

    while(sequence > 0) {
        hInsertionSort(tab, sequence);
        k--;
        sequence = (int)(Math.pow(3, k) - 1) / 2;
    }
}

public static void hInsertionSort(int[] tab, int h) {
    int N = tab.length;
    int k = 0;
    while (k < h) {
        for (int i = k; i < N; i+=h) {
            for (int j = i; j > k+h-1; j-=h) {
                if (less(tab[j], tab[j-h]) == -1) exch(tab, j, j-h);
                else break;
            }
        }
    k++;
    }

}

private static inttab[1] (it means sort tab[1], tab[h+1], ...). This is h-sorting your array. less(int value1, int value2) {
        if (value1 == value2) return 0;
        if (value1 < value2) return -1;
        else return 1;
}
tab[1] (it means sort tab[1], tab[h+1], ...). This is h-sorting your array.
private static void exch(int[] tab, int key1, int key2) {
        int inter;
        inter = tab[key1];
        tab[key1] = tab[key2];
        tab[key2] = inter;
}
相关问题