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是每個元素複製的時間
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章