21. 排序--表排序

表排序

又称间接排序,排序时不调整元素的实际位置,而是定义一个额外的数组作为“表”(table)。根据元素的关键字大小来调整元素对应下标在表中的位置。

初始

A [0] [1] [2] [3] [4] [5] [6] [7]
key f d c a g b h e
table 0 1 2 3 4 5 6 7

初始的一个结构体数组,需要根据key的大小来进行排序,但是这里只调整table中下标的位置。表排序在调整下标的位置时可以使用其他的排序算法,例如直接插入排序。

调整后

A [0] [1] [2] [3] [4] [5] [6] [7]
key f d c a g b h e
table 3 5 2 1 7 0 4 6

如果仅要求按顺序输出,则输出:A[table[0]],A[table[1]],...,A[table[N1]]

物理排序

经过表排序后,得到了排好序的table数组,但是如果需要调整元素的实际位置,那就需要物理排序。

实现

  • N个数字的排序由若干个独立的环组成
  • 在每个环中进行元素实际位置的交换
    • 使用temp来保存第一个元素
    • A[table[i]]的元素放置于i,同时修改table[i] = i
    • 如果table[i] == i说明环结束,并把temp置于这个位置
struct Element {
    ElementType Data;   // data可以是任意类型
    ElementType key;    // 关键字只要可比即可
}

// 物理排序过程 Elements = 元素数组, table = 表数组,假设表数组已经排好了
void Sort(Element[] Elements, int[] table, int N) {
    for (i = 0; i < N; i++) {
        Temp = Elements[i];
        int j = i;
        while (table[j] != j) {
            Elements[j] = Elements[table[j]];   // 把实际该置于j位置的元素置于J
            NextIndex = table[j];   //  记录下一个元素的位置
            table[j] = j;
            j = NextIndex;          // 让j跳到下一个元素
        }

        if (Elements[j] != Temp) {  // 说明该环不止一个元素,需要进行temp的赋值
            Elements[j] = Temp;
        }
    }
}

复杂度分析

  • 最好情况:初始即有序
  • 最坏情况:
    • N/2 个环,每个环包含2 个元素
    • 需要3N/2 次元素移动
  • T=O(mN) ,m是每个元素复制的时间
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章