天天看點

[資料結構]排序相關算法

[資料結構]排序相關算法

目錄

  • 1.5 排序
    • 1.5.1 直接插入排序
    • 1.5.2 折半插入排序(順序結構)
    • 1.5.3 2—路插入排序(順序結構)
    • 1.5.4 折半插入排序(鍊式結構)
    • 1.5.5 2—路插入排序(鍊式結構)
    • 1.5.6 希爾排序
    • 1.5.7 冒泡排序
    • 1.5.8 一趟快速排序
    • 1.5.9 一趟快速排序的改進算法
    • 1.5.10 簡單選擇排序
    • 1.5.11 箱子排序
    • 1.5.12 樹型選擇排序
    • 1.5.13 堆排序
    • 1.5.14 歸并排序
    • 1.5.15 多路平衡歸并排序
    • 1.5.16 置換—選擇排序
    • 1.5.17 檔案的歸并

#include<stdio.h> /* EOF(=^Z或F6),NULL */

#define N 8
#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
#define LT(a, b) ((a)<(b))
typedef int InfoType; /* 定義其它資料項的類型 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */
typedef struct {
    RedType r[MAXSIZE + 1]; /* r[0]閑置或用作哨兵單元 */
    int length; /* 順序表長度 */
} SqList; /* 順序表類型 */
void InsertSort(SqList *L) { /* 對順序表L作直接插入排序。*/
    int i, j;
    for (i = 2; i <= (*L).length; ++i)
        if LT((*L).r[i].key, (*L).r[i - 1].key) /* "<",需将L.r[i]插入有序子表 */
        {
            (*L).r[0] = (*L).r[i]; /* 複制為哨兵 */
            for (j = i - 1; LT((*L).r[0].key, (*L).r[j].key); --j)
                (*L).r[j + 1] = (*L).r[j]; /* 記錄後移 */
            (*L).r[j + 1] = (*L).r[0]; /* 插入到正确位置 */
        }
}

void print(SqList L) {
    int i;
    for (i = 1; i <= L.length; i++)
        printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo);
    printf("\n");
}

int main() {
    RedType d[N] = {{49, 1},
                    {38, 2},
                    {65, 3},
                    {97, 4},
                    {76, 5},
                    {13, 6},
                    {27, 7},
                    {49, 8}};
    SqList l1;
    int i;
    for (i = 0; i < N; i++) /* 給l1.r指派 */
        l1.r[i + 1] = d[i];
    l1.length = N;
    printf("排序前:\n");
    print(l1);
    InsertSort(&l1);
    printf("直接插入排序後:\n");
    print(l1);
    return 0;
}
           

運作結果

[資料結構]排序相關算法

#include<stdio.h> /* EOF(=^Z或F6),NULL */

#define N 8
#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
#define LT(a, b) ((a)<(b))
typedef int InfoType; /* 定義其它資料項的類型 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */

typedef struct {
    RedType r[MAXSIZE + 1]; /* r[0]閑置或用作哨兵單元 */
    int length; /* 順序表長度 */
} SqList; /* 順序表類型 */
void BInsertSort(SqList *L) { /* 對順序表L作折半插入排序。*/
    int i, j, m, low, high;
    for (i = 2; i <= (*L).length; ++i) {
        (*L).r[0] = (*L).r[i]; /* 将L.r[i]暫存到L.r[0] */
        low = 1;
        high = i - 1;
        while (low <= high) { /* 在r[low..high]中折半查找有序插入的位置 */
            m = (low + high) / 2; /* 折半 */
            if LT((*L).r[0].key, (*L).r[m].key)
                high = m - 1; /* 插入點在低半區 */
            else
                low = m + 1; /* 插入點在高半區 */
        }
        for (j = i - 1; j >= high + 1; --j)
            (*L).r[j + 1] = (*L).r[j]; /* 記錄後移 */
        (*L).r[high + 1] = (*L).r[0]; /* 插入 */
    }
}

void print(SqList L) {
    int i;
    for (i = 1; i <= L.length; i++)
        printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo);
    printf("\n");
}

int main() {
    RedType d[N] = {{49, 1},
                    {38, 2},
                    {65, 3},
                    {97, 4},
                    {76, 5},
                    {13, 6},
                    {27, 7},
                    {49, 8}};
    SqList l1;
    int i;
    for (i = 0; i < N; i++) /* 給l1.r指派 */
        l1.r[i + 1] = d[i];
    l1.length = N;
    printf("排序前:\n");
    print(l1);
    BInsertSort(&l1);
    printf("折半插入排序後:\n");
    print(l1);
    return 0;
}
           
[資料結構]排序相關算法

#include <stdio.h> /* EOF(=^Z或F6),NULL */
#include <stdlib.h>

#define N 8
#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
#define LT(a, b) ((a)<(b))
typedef int InfoType; /* 定義其它資料項的類型 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */
typedef struct {
    RedType r[MAXSIZE + 1]; /* r[0]閑置或用作哨兵單元 */
    int length; /* 順序表長度 */
} SqList; /* 順序表類型 */
void P2_InsertSort(SqList *L) { /* 2_路插入排序 */
    int i, j, first, final;
    RedType *d;
    d = (RedType *) malloc((*L).length * sizeof(RedType)); /* 生成L.length個記錄的臨時空間 */
    d[0] = (*L).r[1]; /* 設L的第1個記錄為d中排好序的記錄(在位置[0]) */
    first = final = 0; /* first、final分别訓示d中排好序的記錄的第1個和最後1個記錄的位置 */
    for (i = 2; i <= (*L).length; ++i) { /* 依次将L的第2個~最後1個記錄插入d中 */
        if ((*L).r[i].key < d[first].key) { /* 待插記錄小于d中最小值,插到d[first]之前(不需移動d數組的元素) */
            first = (first - 1 + (*L).length) % (*L).length; /* 設d為循環向量 */
            d[first] = (*L).r[i];
        } else if ((*L).r[i].key > d[final].key) { /* 待插記錄大于d中最大值,插到d[final]之後(不需移動d數組的元素) */
            final = final + 1;
            d[final] = (*L).r[i];
        } else { /* 待插記錄大于d中最小值,小于d中最大值,插到d的中間(需要移動d數組的元素) */
            j = final++; /* 移動d的尾部元素以便按序插入記錄 */
            while ((*L).r[i].key < d[j].key) {
                d[(j + 1) % (*L).length] = d[j];
                j = (j - 1 + (*L).length) % (*L).length;
            }
            d[j + 1] = (*L).r[i];
        }
    }
    for (i = 1; i <= (*L).length; i++) /* 把d賦給L.r */
        (*L).r[i] = d[(i + first - 1) % (*L).length]; /* 線性關系 */
}

void print(SqList L) {
    int i;
    for (i = 1; i <= L.length; i++)
        printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo);
    printf("\n");
}

int main() {
    RedType d[N] = {{49, 1},
                    {38, 2},
                    {65, 3},
                    {97, 4},
                    {76, 5},
                    {13, 6},
                    {27, 7},
                    {49, 8}};
    SqList l1;
    int i;
    for (i = 0; i < N; i++) /* 給l1.r指派 */
        l1.r[i + 1] = d[i];
    l1.length = N;
    printf("排序前:\n");
    print(l1);
    P2_InsertSort(&l1);
    printf("2_路插入排序後:\n");
    print(l1);
}
           
[資料結構]排序相關算法

#include<limits.h> /* INT_MAX等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<stdlib.h> /* atoi() */

#define N 8
#define SIZE 100 /* 靜态連結清單容量 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef int InfoType; /* 定義其它資料項的類型 */
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */

typedef struct {
    RedType rc; /* 記錄項 */
    int next; /* 指針項 */
} SLNode; /* 表結點類型 */
typedef struct {
    SLNode r[SIZE]; /* 0号單元為表頭結點 */
    int length; /* 連結清單目前長度 */
} SLinkListType; /* 靜态連結清單類型 */
void TableInsert(SLinkListType *SL, RedType D[], int n) { /* 由數組D建立n個元素的表插入排序的靜态連結清單SL */
    int i, p, q;
    (*SL).r[0].rc.key = INT_MAX; /* 表頭結點記錄的關鍵字取最大整數(非降序連結清單的表尾) */
    (*SL).r[0].next = 0; /* next域為0表示表尾(現為空表,初始化) */
    for (i = 0; i < n; i++) {
        (*SL).r[i + 1].rc = D[i]; /* 将數組D的值賦給靜态連結清單SL */
        q = 0;
        p = (*SL).r[0].next;
        while ((*SL).r[p].rc.key <= (*SL).r[i + 1].rc.key) { /* 靜态連結清單向後移 */
            q = p;
            p = (*SL).r[p].next;
        }
        (*SL).r[i + 1].next = p; /* 将目前記錄插入靜态連結清單 */
        (*SL).r[q].next = i + 1;
    }
    (*SL).length = n;
}

void Arrange(SLinkListType *SL) { /* 根據靜态連結清單SL中各結點的指針值調整記錄位置,使得SL中記錄按關鍵字 */
    /* 非遞減有序順序排列*/
    int i, p, q;
    SLNode t;
    p = (*SL).r[0].next; /* p訓示第一個記錄的目前位置 */
    for (i = 1; i < (*SL).length; ++i) { /* (*SL).r[1..i-1]中記錄已按關鍵字有序排列,第i個記錄在SL中的目前位置應不小于i */
        while (p < i)
            p = (*SL).r[p].next; /* 找到第i個記錄,并用p訓示其在SL中目前位置 */
        q = (*SL).r[p].next; /* q訓示尚未調整的表尾 */
        if (p != i) {
            t = (*SL).r[p]; /* 交換記錄,使第i個記錄到位 */
            (*SL).r[p] = (*SL).r[i];
            (*SL).r[i] = t;
            (*SL).r[i].next = p; /* 指向被移走的記錄,使得以後可由while循環找回 */
        }
        p = q; /* p訓示尚未調整的表尾,為找第i+1個記錄作準備 */
    }
}

void Sort(SLinkListType L, int adr[]) { /* 求得adr[1..L.length],adr[i]為靜态連結清單L的第i個最小記錄的序号 */
    int i = 1, p = L.r[0].next;
    while (p) {
        adr[i++] = p;
        p = L.r[p].next;
    }
}

void print(SLinkListType L) {
    int i;
    for (i = 1; i <= L.length; i++)
        printf("key=%d ord=%d next=%d\n", L.r[i].rc.key, L.r[i].rc.otherinfo, L.r[i].next);
}

int main() {
    RedType d[N] = {{49, 1},
                    {38, 2},
                    {65, 3},
                    {97, 4},
                    {76, 5},
                    {13, 6},
                    {27, 7},
                    {49, 8}};
    SLinkListType l1;
    int *adr, i;
    TableInsert(&l1, d, N);
    printf("排序前:\n");
    print(l1);
    Arrange(&l1);
    printf("l1排序後:\n");
    print(l1);
    return 0;
}
           
[資料結構]排序相關算法

#include <limits.h> /* INT_MAX等 */
#include <stdio.h> /* EOF(=^Z或F6),NULL */
#include <stdlib.h>

#define N 8
#define SIZE 100 /* 靜态連結清單容量 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef int InfoType; /* 定義其它資料項的類型 */
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */

typedef struct {
    RedType rc; /* 記錄項 */
    int next; /* 指針項 */
} SLNode; /* 表結點類型 */
typedef struct {
    SLNode r[SIZE]; /* 0号單元為表頭結點 */
    int length; /* 連結清單目前長度 */
} SLinkListType; /* 靜态連結清單類型 */
void TableInsert(SLinkListType *SL, RedType D[], int n) { /* 由數組D建立n個元素的表插入排序的靜态連結清單SL */
    int i, p, q;
    (*SL).r[0].rc.key = INT_MAX; /* 表頭結點記錄的關鍵字取最大整數(非降序連結清單的表尾) */
    (*SL).r[0].next = 0; /* next域為0表示表尾(現為空表,初始化) */
    for (i = 0; i < n; i++) {
        (*SL).r[i + 1].rc = D[i]; /* 将數組D的值賦給靜态連結清單SL */
        q = 0;
        p = (*SL).r[0].next;
        while ((*SL).r[p].rc.key <= (*SL).r[i + 1].rc.key) { /* 靜态連結清單向後移 */
            q = p;
            p = (*SL).r[p].next;
        }
        (*SL).r[i + 1].next = p; /* 将目前記錄插入靜态連結清單 */
        (*SL).r[q].next = i + 1;
    }
    (*SL).length = n;
}

void Sort(SLinkListType L, int adr[]) { /* 求得adr[1..L.length],adr[i]為靜态連結清單L的第i個最小記錄的序号 */
    int i = 1, p = L.r[0].next;
    while (p) {
        adr[i++] = p;
        p = L.r[p].next;
    }
}

void Rearrange(SLinkListType *L, int adr[]) { /* adr給出靜态連結清單L的有序次序,即L.r[adr[i]]是第i小的記錄。 */
    int i, j, k;
    for (i = 1; i < (*L).length; ++i)
        if (adr[i] != i) {
            j = i;
            (*L).r[0] = (*L).r[i]; /* 暫存記錄(*L).r[i] */
            while (adr[j] != i) { /* 調整(*L).r[adr[j]]的記錄到位直到adr[j]=i為止 */
                k = adr[j];
                (*L).r[j] = (*L).r[k];
                adr[j] = j;
                j = k; /* 記錄按序到位 */
            }
            (*L).r[j] = (*L).r[0];
            adr[j] = j;
        }
}

void print(SLinkListType L) {
    int i;
    for (i = 1; i <= L.length; i++)
        printf("key=%d ord=%d next=%d\n", L.r[i].rc.key, L.r[i].rc.otherinfo, L.r[i].next);
}

int main() {
    RedType d[N] = {{49, 1},
                    {38, 2},
                    {65, 3},
                    {97, 4},
                    {76, 5},
                    {13, 6},
                    {27, 7},
                    {49, 8}};
    SLinkListType l1;
    int *adr, i;
    TableInsert(&l1, d, N);
    printf("排序前:\n");
    print(l1);
    adr = (int *) malloc((l1.length + 1) * sizeof(int));
    Sort(l1, adr);
    for (i = 1; i <= l1.length; i++)
        printf("adr[%d]=%d ", i, adr[i]);
    printf("\n");
    Rearrange(&l1, adr);
    printf("l1排序後:\n");
    print(l1);
    return 0;
}
           
[資料結構]排序相關算法

#include<stdio.h>

#define N 10
#define T 3
#define LT(a, b) ((a)<(b))
#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
typedef int InfoType; /* 定義其它資料項的類型 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */

typedef struct {
    RedType r[MAXSIZE + 1]; /* r[0]閑置或用作哨兵單元 */
    int length; /* 順序表長度 */
} SqList; /* 順序表類型 */
void ShellInsert(SqList *L, int dk) { /* 對順序表L作一趟希爾插入排序。本算法是和一趟直接插入排序相比, */
    /* 作了以下修改: */
    /* 1.前後記錄位置的增量是dk,而不是1; */
    /* 2.r[0]隻是暫存單元,不是哨兵。當j<=0時,插入位置已找到。*/
    int i, j;
    for (i = dk + 1; i <= (*L).length; ++i)
        if LT((*L).r[i].key, (*L).r[i - dk].key) { /* 需将(*L).r[i]插入有序增量子表 */
            (*L).r[0] = (*L).r[i]; /* 暫存在(*L).r[0] */
            for (j = i - dk; j > 0 && LT((*L).r[0].key, (*L).r[j].key); j -= dk)
                (*L).r[j + dk] = (*L).r[j]; /* 記錄後移,查找插入位置 */
            (*L).r[j + dk] = (*L).r[0]; /* 插入 */
        }
}

void print(SqList L) {
    int i;
    for (i = 1; i <= L.length; i++)
        printf("%d ", L.r[i].key);
    printf("\n");
}

void print1(SqList L) {
    int i;
    for (i = 1; i <= L.length; i++)
        printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo);
    printf("\n");
}

void ShellSort(SqList *L, int dlta[], int t) { /* 按增量序列dlta[0..t-1]對順序表L作希爾排序。*/
    int k;
    for (k = 0; k < t; ++k) {
        ShellInsert(L, dlta[k]); /* 一趟增量為dlta[k]的插入排序 */
        printf("第%d趟排序結果: ", k + 1);
        print(*L);
    }
}

int main() {
    RedType d[N] = {{49, 1},
                    {38, 2},
                    {65, 3},
                    {97, 4},
                    {76, 5},
                    {13, 6},
                    {27, 7},
                    {49, 8},
                    {55, 9},
                    {4,  10}};
    SqList l;
    int i, dt[T] = {5, 3, 1}; /* 增量序列數組 */
    for (i = 0; i < N; i++)
        l.r[i + 1] = d[i];
    l.length = N;
    printf("排序前: ");
    print(l);
    ShellSort(&l, dt, T);
    printf("排序後: ");
    print1(l);
    return 0;
}
           
[資料結構]排序相關算法

#include<stdio.h> /* EOF(=^Z或F6),NULL */

#define TRUE 1
#define FALSE 0
typedef int Status; /* Status是函數的類型,其值是函數結果狀态代碼,如OK等 */
#define N 8

void bubble_sort(int a[], int n) { /* 将a中整數序列重新排列成自小至大有序的整數序列(起泡排序) */
    int i, j, t;
    Status change;
    for (i = n - 1, change = TRUE; i > 1 && change; --i) {
        change = FALSE;
        for (j = 0; j < i; ++j)
            if (a[j] > a[j + 1]) {
                t = a[j];
                a[j] = a[j + 1];
                a[j + 1] = t;
                change = TRUE;
            }
    }
}

void print(int r[], int n) {
    int i;
    for (i = 0; i < n; i++)
        printf("%d ", r[i]);
    printf("\n");
}

int main() {
    int d[N] = {49, 38, 65, 97, 76, 13, 27, 49};
    printf("排序前:\n");
    print(d, N);
    bubble_sort(d, N);
    printf("排序後:\n");
    print(d, N);
    return 0;
}
           
[資料結構]排序相關算法

#include<stdio.h>

#define N 8
#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef int InfoType;
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */

typedef struct {
    RedType r[MAXSIZE + 1]; /* r[0]閑置或用作哨兵單元 */
    int length; /* 順序表長度 */
} SqList; /* 順序表類型 */
int Partition(SqList *L, int low, int high) { /* 交換順序表L中子表r[low..high]的記錄,樞軸記錄到位,并傳回其 */
    /* 所在位置,此時在它之前(後)的記錄均不大(小)于它。*/
    KeyType pivotkey;
    (*L).r[0] = (*L).r[low]; /* 用子表的第一個記錄作樞軸記錄 */
    pivotkey = (*L).r[low].key; /* 樞軸記錄關鍵字 */
    while (low < high) { /* 從表的兩端交替地向中間掃描 */
        while (low < high && (*L).r[high].key >= pivotkey)
            --high;
        (*L).r[low] = (*L).r[high]; /* 将比樞軸記錄小的記錄移到低端 */
        while (low < high && (*L).r[low].key <= pivotkey)
            ++low;
        (*L).r[high] = (*L).r[low]; /* 将比樞軸記錄大的記錄移到高端 */
    }
    (*L).r[low] = (*L).r[0]; /* 樞軸記錄到位 */
    return low; /* 傳回樞軸位置 */
}

void QSort(SqList *L, int low, int high) { /* 對順序表L中的子序列L.r[low..high]作快速排序。*/
    int pivotloc;
    if (low < high) { /* 長度大于1 */
        pivotloc = Partition(L, low, high); /* 将L.r[low..high]一分為二 */
        QSort(L, low, pivotloc - 1); /* 對低子表遞歸排序,pivotloc是樞軸位置 */
        QSort(L, pivotloc + 1, high); /* 對高子表遞歸排序 */
    }
}

void QuickSort(SqList *L) { /* 對順序表L作快速排序。*/
    QSort(L, 1, (*L).length);
}

void print(SqList L) {
    int i;
    for (i = 1; i <= L.length; i++)
        printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo);
    printf("\n");
}

int main() {
    RedType d[N] = {{49, 1},
                    {38, 2},
                    {65, 3},
                    {97, 4},
                    {76, 5},
                    {13, 6},
                    {27, 7},
                    {49, 8}};
    SqList l;
    int i;
    for (i = 0; i < N; i++)
        l.r[i + 1] = d[i];
    l.length = N;
    printf("排序前:\n");
    print(l);
    QuickSort(&l);
    printf("排序後:\n");
    print(l);
    return 0;
}
           
[資料結構]排序相關算法

#include<stdio.h>

#define N 8
#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef int InfoType;
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */

typedef struct {
    RedType r[MAXSIZE + 1]; /* r[0]閑置或用作哨兵單元 */
    int length; /* 順序表長度 */
} SqList; /* 順序表類型 */
int Partition(SqList *L, int low, int high) { /* 交換順序表L中子表r[low..high]的記錄,樞軸記錄到位,并傳回其 */
    /* 所在位置,此時在它之前(後)的記錄均不大(小)于它。*/
    KeyType pivotkey;
    (*L).r[0] = (*L).r[low]; /* 用子表的第一個記錄作樞軸記錄 */
    pivotkey = (*L).r[low].key; /* 樞軸記錄關鍵字 */
    while (low < high) { /* 從表的兩端交替地向中間掃描 */
        while (low < high && (*L).r[high].key >= pivotkey)
            --high;
        (*L).r[low] = (*L).r[high]; /* 将比樞軸記錄小的記錄移到低端 */
        while (low < high && (*L).r[low].key <= pivotkey)
            ++low;
        (*L).r[high] = (*L).r[low]; /* 将比樞軸記錄大的記錄移到高端 */
    }
    (*L).r[low] = (*L).r[0]; /* 樞軸記錄到位 */
    return low; /* 傳回樞軸位置 */
}

void QSort(SqList *L, int low, int high) { /* 對順序表L中的子序列L.r[low..high]作快速排序。*/
    int pivotloc;
    if (low < high) { /* 長度大于1 */
        pivotloc = Partition(L, low, high); /* 将L.r[low..high]一分為二 */
        QSort(L, low, pivotloc - 1); /* 對低子表遞歸排序,pivotloc是樞軸位置 */
        QSort(L, pivotloc + 1, high); /* 對高子表遞歸排序 */
    }
}

void QuickSort(SqList *L) { /* 對順序表L作快速排序。*/
    QSort(L, 1, (*L).length);
}

void print(SqList L) {
    int i;
    for (i = 1; i <= L.length; i++)
        printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo);
    printf("\n");
}

int main() {
    RedType d[N] = {{49, 1},
                    {38, 2},
                    {65, 3},
                    {97, 4},
                    {76, 5},
                    {13, 6},
                    {27, 7},
                    {49, 8}};
    SqList l;
    int i;
    for (i = 0; i < N; i++)
        l.r[i + 1] = d[i];
    l.length = N;
    printf("排序前:\n");
    print(l);
    QuickSort(&l);
    printf("排序後:\n");
    print(l);
    return 0;
}
           
[資料結構]排序相關算法

#include<stdio.h>

#define N 8
#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
typedef int InfoType; /* 定義其它資料項的類型 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */
typedef struct {
    RedType r[MAXSIZE + 1]; /* r[0]閑置或用作哨兵單元 */
    int length; /* 順序表長度 */
} SqList; /* 順序表類型 */
int SelectMinKey(SqList L, int i) { /* 傳回在L.r[i..L.length]中key最小的記錄的序号 */
    KeyType min;
    int j, k;
    k = i; /* 設第i個為最小 */
    min = L.r[i].key;
    for (j = i + 1; j <= L.length; j++)
        if (L.r[j].key < min) /* 找到更小的 */
        {
            k = j;
            min = L.r[j].key;
        }
    return k;
}

void SelectSort(SqList *L) { /* 對順序表L作簡單選擇排序。*/
    int i, j;
    RedType t;
    for (i = 1; i < (*L).length; ++i) { /*  選擇第i小的記錄,并交換到位 */
        j = SelectMinKey(*L, i); /* 在L.r[i..L.length]中選擇key最小的記錄 */
        if (i != j) { /* 與第i個記錄交換 */
            t = (*L).r[i];
            (*L).r[i] = (*L).r[j];
            (*L).r[j] = t;
        }
    }
}

void print(SqList L) {
    int i;
    for (i = 1; i <= L.length; i++)
        printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo);
    printf("\n");
}

int main() {
    RedType d[N] = {{49, 1},
                    {38, 2},
                    {65, 3},
                    {97, 4},
                    {76, 5},
                    {13, 6},
                    {27, 7},
                    {49, 8}};
    SqList l;
    int i;
    for (i = 0; i < N; i++)
        l.r[i + 1] = d[i];
    l.length = N;
    printf("排序前:\n");
    print(l);
    SelectSort(&l);
    printf("排序後:\n");
    print(l);
    return 0;
}
           
[資料結構]排序相關算法

#include "stdio.h"

#define num_arr    5
typedef struct attr {
    int key;
    char name[10];
} ArrType;

void sort(ArrType A[]) {
    int i;
    ArrType B[num_arr];
    for (i = 0; i < num_arr; i++)
        B[A[i].key] = A[i];
    for (i = 0; i < num_arr; i++)
        printf("%s\n", B[i].name);
}

int main() {
    ArrType c[num_arr] = {{4, "John"},
                          {1, "Jane"},
                          {0, "Alice"},
                          {2, "Peter"},
                          {3, "Tom"}};
    sort(c);
    return 0;
}

           
[資料結構]排序相關算法

#include<limits.h> /* INT_MAX等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<math.h> /* floor(),ceil(),abs() */

#define N 8
#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
typedef int InfoType; /* 定義其它資料項的類型 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */
typedef struct {
    RedType r[MAXSIZE + 1]; /* r[0]閑置或用作哨兵單元 */
    int length; /* 順序表長度 */
} SqList; /* 順序表類型 */
void TreeSort(SqList *L) { /* 樹形選擇排序 */
    int i, j, j1, k, k1, l, n = (*L).length;
    RedType *t;
    l = (int) ceil(log(n) / log(2)) + 1; /* 完全二叉樹的層數 */
    k = (int) pow(2, l) - 1; /* l層完全二叉樹的結點總數 */
    k1 = (int) pow(2, l - 1) - 1; /* l-1層完全二叉樹的結點總數 */
    t = (RedType *) malloc(k * sizeof(RedType)); /* 二叉樹采用順序存儲結構 */
    for (i = 1; i <= n; i++) /* 将L.r賦給葉子結點 */
        t[k1 + i - 1] = (*L).r[i];
    for (i = k1 + n; i < k; i++) /* 給多餘的葉子的關鍵字賦無窮大 */
        t[i].key = INT_MAX;
    j1 = k1;
    j = k;
    while (j1) { /* 給非葉子結點指派 */
        for (i = j1; i < j; i += 2)
            t[i].key < t[i + 1].key ? (t[(i + 1) / 2 - 1] = t[i]) : (t[(i + 1) / 2 - 1] = t[i + 1]);
        j = j1;
        j1 = (j1 - 1) / 2;
    }
    for (i = 0; i < n; i++) {
        (*L).r[i + 1] = t[0]; /* 将目前最小值賦給L.r[i] */
        j1 = 0;
        for (j = 1; j < l; j++) /* 沿樹根找結點t[0]在葉子中的序号j1 */
            t[2 * j1 + 1].key == t[j1].key ? (j1 = 2 * j1 + 1) : (j1 = 2 * j1 + 2);
        t[j1].key = INT_MAX;
        while (j1) {
            j1 = (j1 + 1) / 2 - 1; /* 序号為j1的結點的雙親結點序号 */
            t[2 * j1 + 1].key <= t[2 * j1 + 2].key ? (t[j1] = t[2 * j1 + 1]) : (t[j1] = t[2 * j1 + 2]);
        }
    }
    free(t);
}

void print(SqList L) {
    int i;
    for (i = 1; i <= L.length; i++)
        printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo);
    printf("\n");
}

int main() {
    RedType d[N] = {{49, 1},
                    {38, 2},
                    {65, 3},
                    {97, 4},
                    {76, 5},
                    {13, 6},
                    {27, 7},
                    {49, 8}};
    SqList l;
    int i;
    for (i = 0; i < N; i++)
        l.r[i + 1] = d[i];
    l.length = N;
    printf("排序前:\n");
    print(l);
    TreeSort(&l);
    printf("排序後:\n");
    print(l);
    return 0;
}
           
[資料結構]排序相關算法

#include<stdio.h>

#define N 8
#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
typedef int InfoType; /* 定義其它資料項的類型 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */
typedef struct {
    RedType r[MAXSIZE + 1]; /* r[0]閑置或用作哨兵單元 */
    int length; /* 順序表長度 */
} SqList; /* 順序表類型 */
#define LT(a, b) ((a)<(b))
typedef SqList HeapType; /* 堆采用順序表存儲表示 */
void HeapAdjust(HeapType *H, int s, int m) { /* 已知H.r[s..m]中記錄的關鍵字除H.r[s].key之外均滿足堆的定義,本函數 */
    /* 調整H.r[s]的關鍵字,使H.r[s..m]成為一個大頂堆(對其中記錄的關鍵字而言) */
    RedType rc;
    int j;
    rc = (*H).r[s];
    for (j = 2 * s; j <= m; j *= 2) { /* 沿key較大的孩子結點向下篩選 */
        if (j < m && LT((*H).r[j].key, (*H).r[j + 1].key))
            ++j; /* j為key較大的記錄的下标 */
        if (!LT(rc.key, (*H).r[j].key))
            break; /* rc應插入在位置s上 */
        (*H).r[s] = (*H).r[j];
        s = j;
    }
    (*H).r[s] = rc; /* 插入 */
}

void HeapSort(HeapType *H) { /* 對順序表H進行堆排序。*/
    RedType t;
    int i;
    for (i = (*H).length / 2; i > 0; --i) /* 把H.r[1..H.length]建成大頂堆 */
        HeapAdjust(H, i, (*H).length);
    for (i = (*H).length; i > 1; --i) { /* 将堆頂記錄和目前未經排序子序列H.r[1..i]中最後一個記錄互相交換 */
        t = (*H).r[1];
        (*H).r[1] = (*H).r[i];
        (*H).r[i] = t;
        HeapAdjust(H, 1, i - 1); /* 将H.r[1..i-1]重新調整為大頂堆 */
    }
}

void print(HeapType H) {
    int i;
    for (i = 1; i <= H.length; i++)
        printf("(%d,%d)", H.r[i].key, H.r[i].otherinfo);
    printf("\n");
}

int main() {
    RedType d[N] = {{49, 1},
                    {38, 2},
                    {65, 3},
                    {97, 4},
                    {76, 5},
                    {13, 6},
                    {27, 7},
                    {49, 8}};
    HeapType h;
    int i;
    for (i = 0; i < N; i++)
        h.r[i + 1] = d[i];
    h.length = N;
    printf("排序前:\n");
    print(h);
    HeapSort(&h);
    printf("排序後:\n");
    print(h);
    return 0;
}
           
[資料結構]排序相關算法

#include<stdio.h>

#define N 7
#define LQ(a, b) ((a)<=(b))
#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef int InfoType; /* 定義其它資料項的類型 */
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */
typedef struct {
    RedType r[MAXSIZE + 1]; /* r[0]閑置或用作哨兵單元 */
    int length; /* 順序表長度 */
} SqList; /* 順序表類型 */
void Merge(RedType SR[], RedType TR[], int i, int m, int n) { /* 将有序的SR[i..m]和SR[m+1..n]歸并為有序的TR[i..n] */
    int j, k, l;
    for (j = m + 1, k = i; i <= m && j <= n; ++k) /* 将SR中記錄由小到大地并入TR */
        if LQ(SR[i].key, SR[j].key)
            TR[k] = SR[i++];
        else
            TR[k] = SR[j++];
    if (i <= m)
        for (l = 0; l <= m - i; l++)
            TR[k + l] = SR[i + l]; /* 将剩餘的SR[i..m]複制到TR */
    if (j <= n)
        for (l = 0; l <= n - j; l++)
            TR[k + l] = SR[j + l]; /* 将剩餘的SR[j..n]複制到TR */
}

void MSort(RedType SR[], RedType TR1[], int s, int t) { /* 将SR[s..t]歸并排序為TR1[s..t]。*/
    int m;
    RedType TR2[MAXSIZE + 1];
    if (s == t)
        TR1[s] = SR[s];
    else {
        m = (s + t) / 2; /* 将SR[s..t]平分為SR[s..m]和SR[m+1..t] */
        MSort(SR, TR2, s, m); /* 遞歸地将SR[s..m]歸并為有序的TR2[s..m] */
        MSort(SR, TR2, m + 1, t); /* 遞歸地将SR[m+1..t]歸并為有序的TR2[m+1..t] */
        Merge(TR2, TR1, s, m, t); /* 将TR2[s..m]和TR2[m+1..t]歸并到TR1[s..t] */
    }
}

void MergeSort(SqList *L) { /* 對順序表L作歸并排序。*/
    MSort((*L).r, (*L).r, 1, (*L).length);
}

void print(SqList L) {
    int i;
    for (i = 1; i <= L.length; i++)
        printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo);
    printf("\n");
}

int main() {
    RedType d[N] = {{49, 1},
                    {38, 2},
                    {65, 3},
                    {97, 4},
                    {76, 5},
                    {13, 6},
                    {27, 7}};
    SqList l;
    int i;
    for (i = 0; i < N; i++)
        l.r[i + 1] = d[i];
    l.length = N;
    printf("排序前:\n");
    print(l);
    MergeSort(&l);
    printf("排序後:\n");
    print(l);
    return 0;
}
           
[資料結構]排序相關算法

#include <random>
#include <time.h>
#include <vector>
#include <array>
#include <algorithm>
#include <fstream>
#include <string>
#include <iostream>

using namespace std;

//建立待排序檔案  包含10萬個随機生成的整數
void CreateFile() {
    ofstream out("test.txt");
    default_random_engine e(time(0));
    uniform_int_distribution<int> u(0, 100000);

    for (int i = 0; i < 100000; i++) {
        out << u(e) << endl;
    }
    out.close();
}

//多路平衡歸并,用來排序整數
const int BuffSize = 10000;//假設最大緩存空間為10000
const int merge_K = 4;//歸并的路數

//一開始使用的内排序算法,對10萬條資料進行排序,生成10個各自包含10000條有序資料的檔案
int InnerSort(string filepath) {
    ifstream in(filepath);
    ofstream out;
    vector<int> list;
    int filenum = 0;
    string temp;
    while (true) {
        while (list.size() < BuffSize) {
            if (in >> temp) {
                list.push_back(stoi(temp));
            } else break;
        }
        if (list.size() == 0)break;
        sort(list.begin(), list.end());
        out.open("subsection_0_" + to_string(filenum) + ".txt");
        for (auto val : list)out << to_string(val) << endl;//寫入資料
        out.close();
        list.clear();
        filenum++;
    }
    in.close();
    return filenum;
}

//敗者樹相關
int Adjust(array<int, merge_K - 1> &lossertree, array<vector<int>::iterator, merge_K + 1> inputbfIterators, int index) {
    int winner = index;
    index = index + merge_K - 1;
    while (index > 0) {
        if (*(inputbfIterators[winner]) > *(inputbfIterators[lossertree[(index - 1) / 2]])) {
            int temp = winner;
            winner = lossertree[(index - 1) / 2];
            lossertree[(index - 1) / 2] = temp;
        }
        index = (index - 1) / 2;
    }
    return winner;
}

int CreateLosserTree(array<int, merge_K - 1> &lossertree, array<vector<int>::iterator, merge_K + 1> inputbfIterators) {
    int winner = 0;
    for (int i = lossertree.size() - 1; i >= 0; i--) lossertree[i] = merge_K;
    for (int i = 0; i < merge_K; i++) winner = Adjust(lossertree, inputbfIterators, i);
    return winner;
}

//K路平衡歸并
void K_Merge_Sort(string filepath) {
    int filenum = InnerSort(filepath);
    const int buffersSize = BuffSize / (merge_K + 1);//merge_K個讀入資料的buffer,1個寫出資料的buffer
    array<vector<int>, merge_K> inputBuffer;
    vector<int> minval;
    minval.push_back(-1);
    array<vector<int>::iterator, merge_K + 1> inputbfIterators;
    inputbfIterators[merge_K] = minval.begin();
    vector<int> outputBuffer;
    int mergenum = 0;
    string temp;
    while (filenum > 1) {
        cout << "第" << mergenum + 1 << "輪歸并" << endl;
        for (int i = 0; i < (filenum + merge_K - 1) / merge_K; i++) {
            array<ifstream, merge_K> reader;
            const int num_in_merge = ((i + 1) * merge_K < filenum) ? merge_K : (filenum % merge_K);//目前同時進行歸并的段數
            for (int j = 0; j < merge_K; j++) {
                if (j < num_in_merge) {
                    reader[j].open("subsection_" + to_string(mergenum) + "_" + to_string(i * merge_K + j) + ".txt");
                    inputBuffer[j].clear();
                    for (int k = 0; k < buffersSize; k++) {
                        if (reader[j] >> temp)inputBuffer[j].push_back(stoi(temp));
                        else break;
                    }
                } else {
                    inputBuffer[j].push_back(0x3f3f3f3f);
                }
                inputbfIterators[j] = inputBuffer[j].begin();
            }
            ofstream writer("subsection_" + to_string(mergenum + 1) + "_" + to_string(i) + ".txt");
            outputBuffer.clear();
            array<int, merge_K - 1> lossertree;
            int winner = CreateLosserTree(lossertree, inputbfIterators);
            int value = 0;
            while (true) {
                for (int j = 0; j < num_in_merge; j++) {
                    if (inputbfIterators[j] == inputBuffer[j].end()) {
                        inputBuffer[j].clear();
                        for (int k = 0; k < buffersSize; k++) {
                            if (reader[j] >> temp)inputBuffer[j].push_back(stoi(temp));
                            else {
                                inputBuffer[j].push_back(0x3f3f3f3f);
                                break;
                            }
                        }
                        inputbfIterators[j] = inputBuffer[j].begin();
                    }
                }
                if (outputBuffer.size() >= buffersSize) {
                    for (auto item : outputBuffer)writer << to_string(item) << endl;
                    value += outputBuffer.size();
                    outputBuffer.clear();
                }
                winner = Adjust(lossertree, inputbfIterators, winner);
                if (*(inputbfIterators[winner]) != 0x3f3f3f3f)outputBuffer.push_back(*(inputbfIterators[winner]++));
                else break;
            }
            if (outputBuffer.size() > 0) {
                for (auto item : outputBuffer)writer << to_string(item);
                value += outputBuffer.size();
            }
            cout << "檔案  " << "subsection_" + to_string(mergenum + 1) + "_" + to_string(i) + ".txt 歸并完畢 " << "資料數量"
                 << value << endl;
        }
        filenum = (filenum + merge_K - 1) / merge_K;
        mergenum++;
    }
}

int main() {
    CreateFile();
    K_Merge_Sort("test.txt");
}

           
[資料結構]排序相關算法

#include<limits.h> /* INT_MAX等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include <cstring>
#include <iostream>

#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
#define MAXKEY INT_MAX
#define RUNEND_SYMBOL INT_MAX
#define w 6 /* 記憶體工作區可容納的記錄個數 */
#define M 10 /* 設輸出M個資料換行 */
#define N 24 /* 設大檔案有N個資料 */
using namespace std;
typedef int InfoType; /* 定義其它資料項的類型 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */
typedef struct {
    RedType r[MAXSIZE + 1]; /* r[0]閑置或用作哨兵單元 */
    int length; /* 順序表長度 */
} SqList; /* 順序表類型 */
typedef int LoserTree[w]; /* 敗者樹是完全二叉樹且不含葉子,可采用順序存儲結構 */
typedef struct {
    RedType rec; /* 記錄 */
    KeyType key; /* 從記錄中抽取的關鍵字 */
    int rnum; /* 所屬歸并段的段号 */
} RedNode, WorkArea[w]; /* 記憶體工作區,容量為w */

void Select_MiniMax(LoserTree ls, WorkArea wa, int q) { /* 從wa[q]起到敗者樹的根比較選擇MINIMAX記錄,并由q訓示它所在的歸并段 */
    int p, s, t;
    for (t = (w + q) / 2, p = ls[t]; t > 0; t = t / 2, p = ls[t])
        if (wa[p].rnum < wa[q].rnum || wa[p].rnum == wa[q].rnum && wa[p].key < wa[q].key) {
            s = q;
            q = ls[t]; /* q訓示新的勝利者 */
            ls[t] = s;
        }
    ls[0] = q;
}

void Construct_Loser(LoserTree ls, WorkArea wa, FILE *fi) { /* 輸入w個記錄到記憶體工作區wa,建得敗者樹ls,選出關鍵字最小的記錄并由s訓示 */
    /* 其在wa中的位置。*/
    int i;
    for (i = 0; i < w; ++i)
        wa[i].rnum = wa[i].key = ls[i] = 0; /* 工作區初始化 */
    for (i = w - 1; i >= 0; --i) {
        fread(&wa[i].rec, sizeof(RedType), 1, fi); /* 輸入一個記錄 */
        wa[i].key = wa[i].rec.key; /* 提取關鍵字 */
        wa[i].rnum = 1; /* 其段号為"1" */
        Select_MiniMax(ls, wa, i); /* 調整敗者 */
    }
}

void get_run(LoserTree ls, WorkArea wa, int rc, int *rmax, FILE *fi, FILE *fo) { /* 求得一個初始歸并段,fi為輸入檔案指針,fo為輸出檔案指針。*/
    int q;
    KeyType minimax;
    while (wa[ls[0]].rnum == rc) /* 選得的MINIMAX記錄屬目前段時 */
    {
        q = ls[0]; /* q訓示MINIMAX記錄在wa中的位置 */
        minimax = wa[q].key;
        fwrite(&wa[q].rec, sizeof(RedType), 1, fo); /* 将剛選得的MINIMAX記錄寫入輸出檔案 */
        fread(&wa[q].rec, sizeof(RedType), 1, fi); /* 從輸入檔案讀入下一記錄(改) */
        if (feof(fi)) { /* 輸入檔案結束,虛設記錄(屬"rmax+1"段) */
            wa[q].rnum = *rmax + 1;
            wa[q].key = MAXKEY;
        } else { /* 輸入檔案非空時 */
            wa[q].key = wa[q].rec.key; /* 提取關鍵字 */
            if (wa[q].key < minimax) { /* 新讀入的記錄屬下一段 */
                *rmax = rc + 1;
                wa[q].rnum = *rmax;
            } else /* 新讀入的記錄屬目前段 */
                wa[q].rnum = rc;
        }
        Select_MiniMax(ls, wa, q); /* 選擇新的MINIMAX記錄 */
    }
}

void Replace_Selection(LoserTree ls, WorkArea wa, FILE *fi, FILE *fo) { /* 在敗者樹ls和記憶體工作區wa上用置換-選擇排序求初始歸并段,fi為輸入檔案 */
    /* (隻讀檔案)指針,fo為輸出檔案(隻寫檔案)指針,兩個檔案均已打開。*/
    int rc, rmax;
    RedType j;
    j.key = RUNEND_SYMBOL;
    Construct_Loser(ls, wa, fi); /* 初建敗者樹 */
    rc = rmax = 1; /* rc訓示目前生成的初始歸并段的段号,rmax訓示wa中關鍵字所屬初始歸并段的最大段号 */
    while (rc <= rmax) /* "rc=rmax+1"标志輸入檔案的置換-選擇排序已完成 */
    {
        get_run(ls, wa, rc, &rmax, fi, fo); /* 求得一個初始歸并段 */
        j.otherinfo = rc;
        fwrite(&j, sizeof(RedType), 1, fo); /* 将段結束标志寫入輸出檔案 */
        rc = wa[ls[0]].rnum; /* 設定下一段的段号 */
    }
}

void print(RedType t) {
    printf("(%d,%d)", t.key, t.otherinfo);
}

int atoi(char s[]) {
    int i, n, sign;
    for (i = 0; isspace(s[i]); i++)//跳過空白符;
        sign = (s[i] == '-') ? -1 : 1;
    if (s[i] == '+' || s[i] == ' -')//跳過符号
        i++;
    for (n = 0; isdigit(s[i]); i++)
        n = 10 * n + (s[i] - '0');//将數字字元轉換成整形數字
    return sign * n;
}

void itoa(int n, char s[]) {
    int i, j, sign;
    if ((sign = n) < 0)//記錄符号
        n = -n;//使n成為正數
    i = 0;
    do {
        s[i++] = n % 10 + '0';//取下一個數字
    } while ((n /= 10) > 0);//删除該數字
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    for (j = i; j >= 0; j--)//生成的數字是逆序的,是以要逆序輸出
        printf("%c", s[j]);
}

int main() {
    RedType b, a[N] = {{51, 1},
                       {49, 2},
                       {39, 3},
                       {46, 4},
                       {38, 5},
                       {29, 6},
                       {14, 7},
                       {61, 8},
                       {15, 9},
                       {30, 10},
                       {1,  11},
                       {48, 12},
                       {52, 13},
                       {3,  14},
                       {63, 15},
                       {27, 16},
                       {4,  17},
                       {13, 18},
                       {89, 19},
                       {24, 20},
                       {46, 21},
                       {58, 22},
                       {33, 23},
                       {76, 24}};
    FILE *fi, *fo;
    LoserTree ls;
    WorkArea wa;
    int i, k, j = RUNEND_SYMBOL;
    char s[3], fname[4];
    fo = fopen("ori", "wb"); /* 以寫的方式打開大檔案ori */
    fwrite(a, sizeof(RedType), N, fo); /* 将數組a寫入大檔案ori */
    fclose(fo);
    fi = fopen("ori", "rb"); /* 以讀的方式重新打開大檔案ori */
    printf("大檔案的記錄為:\n");
    for (i = 1; i <= N; i++) {
        fread(&b, sizeof(RedType), 1, fi); /* 依次将大檔案ori的資料讀入b */
        print(b); /* 輸出b的内容 */
        if (i % M == 0)
            printf("\n");
    }
    printf("\n");
    rewind(fi); /* 使fi的指針重新傳回大檔案ori的起始位置,以便重新讀入記憶體,産生有序的子檔案 */
    fo = fopen("out", "wb"); /* 以寫的方式打開初始歸并段檔案out */
    Replace_Selection(ls, wa, fi, fo); /* 用置換-選擇排序求初始歸并段 */
    fclose(fo);
    fclose(fi);
    fi = fopen("out", "rb"); /* 以讀的方式重新打開初始歸并段檔案out */
    printf("初始歸并段檔案的記錄為:\n");
    i = 1;
    do {
        k = fread(&b, sizeof(RedType), 1, fi); /* 依次将大檔案out的資料讀入b */
        if (k == 1) {
            print(b); /* 輸出b的内容 */
            if (i++ % M == 0)
                printf("\n");
        }
    } while (k == 1);
    printf("\n");
    rewind(fi); /* 使fi的指針重新傳回大檔案ori的起始位置,以便重新讀入記憶體,産生有序的子檔案 */
    k = 0;
    while (!feof(fi)) /* 按段輸出初始歸并段檔案out */
    {
        itoa(k, s); /* 依次生成檔案名f0,f1,… */
        strcpy(fname, "f");
        strcat(fname, s);
        fo = fopen(fname, "wb"); /* 依次以寫的方式打開檔案f0,f1,… */
        do {
            i = fread(&b, sizeof(RedType), 1, fi);
            if (i == 1) /* fread()調用成功 */
            {
                fwrite(&b, sizeof(RedType), 1, fo); /* 将b寫入檔案f0,f1,… */
                if (b.key == j) /* 1個歸并段結束 */
                {
                    k++;
                    fclose(fo);
                    break;
                }
            }
        } while (i == 1);
    };
    fclose(fi);
    printf("共産生%d個初始歸并段檔案\n", k);
}
           
[資料結構]排序相關算法

#include<limits.h> /* INT_MAX等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include <cstring>

typedef int InfoType; /* 定義其它資料項的類型 */
#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
#define MINKEY INT_MIN
#define MAXKEY INT_MAX
#define k 3 /* k路歸并 */
#define M 10 /* 設輸出M個資料換行 */
typedef int KeyType; /* 定義關鍵字類型為整型 */
typedef struct {
    KeyType key; /* 關鍵字項 */
    InfoType otherinfo; /* 其它資料項,具體類型在主程中定義 */
} RedType; /* 記錄類型 */

typedef struct {
    RedType r[MAXSIZE + 1]; /* r[0]閑置或用作哨兵單元 */
    int length; /* 順序表長度 */
} SqList; /* 順序表類型 */

FILE *fp[k + 1]; /* k+1個檔案指針(fp[k]為大檔案指針),全局變量 */
typedef int LoserTree[k]; /* 敗者樹是完全二叉樹且不含葉子,可采用順序存儲結構 */
typedef RedType ExNode, External[k + 1]; /* 外結點,有改變 */
External b; /* 全局變量 */
void input(int i, KeyType *a) { /* 從第i個檔案(第i個歸并段)讀入該段目前第1個記錄的關鍵字到外結點 */
    fread(a, sizeof(KeyType), 1, fp[i]);
}

void output(int i) { /* 将第i個檔案(第i個歸并段)中目前的記錄寫至輸出歸并段 */
    ExNode a;
    a.key = b[i].key; /* 目前記錄的關鍵字已讀到b[i].key中 */
    fread(&a.otherinfo, sizeof(InfoType), 1, fp[i]);
    fwrite(&a, sizeof(ExNode), 1, fp[k]);
}

void Adjust(LoserTree ls, int s) { /* 沿從葉子結點b[s]到根結點ls[0]的路徑調整敗者樹。算法11.2 */
    int i, t;
    t = (s + k) / 2; /* ls[t]是b[s]的雙親結點 */
    while (t > 0) {
        if (b[s].key > b[ls[t]].key) {
            i = s;
            s = ls[t]; /* s訓示新的勝者 */
            ls[t] = i;
        }
        t = t / 2;
    }
    ls[0] = s;
}

void CreateLoserTree(LoserTree ls) { /* 已知b[0]到b[k-1]為完全二叉樹ls的葉子結點,存有k個關鍵字,沿從葉子 */
    /* 到根的k條路徑将ls調整成為敗者樹。算法11.3 */
    int i;
    b[k].key = MINKEY;
    for (i = 0; i < k; ++i)
        ls[i] = k; /* 設定ls中"敗者"的初值 */
    for (i = k - 1; i >= 0; --i) /* 依次從b[k-1],b[k-2],…,b[0]出發調整敗者 */
        Adjust(ls, i);
}

void K_Merge(LoserTree ls, External b) { /* 利用敗者樹ls将編号從0到k-1的k個輸入歸并段中的記錄歸并到輸出歸并段。 */
    /* b[0]至b[k-1]為敗者樹上的k個葉子結點,分别存放k個輸入歸并段中目前 */
    /* 記錄的關鍵字。算法11.1 */
    int i, q;
    for (i = 0; i < k; ++i) /* 分别從k個輸入歸并段讀人該段目前第一個記錄的關鍵字到外結點 */
        input(i, &b[i].key);
    CreateLoserTree(ls); /* 建敗者樹ls,選得最小關鍵字為b[ls[0]].key */
    while (b[ls[0]].key != MAXKEY) {
        q = ls[0]; /* q訓示目前最小關鍵字所在歸并段 */
        output(q); /* 将編号為q的歸并段中目前(關鍵字為b[q].key)的記錄寫至輸出歸并段 */
        input(q, &b[q].key); /* 從編号為q的輸入歸并段中讀人下一個記錄的關鍵字 */
        Adjust(ls, q); /* 調整敗者樹,選擇新的最小關鍵字 */
    }
    output(ls[0]); /* 将含最大關鍵字MAXKEY的記錄寫至輸出歸并段 */
}

void print(RedType t) {
    printf("(%d,%d)", t.key, t.otherinfo);
}

void itoa(int n, char s[]) {
    int i, j, sign;
    if ((sign = n) < 0)//記錄符号
        n = -n;//使n成為正數
    i = 0;
    do {
        s[i++] = n % 10 + '0';//取下一個數字
    } while ((n /= 10) > 0);//删除該數字
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    for (j = i; j >= 0; j--)//生成的數字是逆序的,是以要逆序輸出
        printf("%c", s[j]);
}

int main() {
    RedType r;
    int i, j;
    char fname[k][4], fout[5] = "out", s[3];
    LoserTree ls;
    for (i = 0; i < k; i++) { /* 依次打開f0,f1,f2,…,k個檔案 */
        itoa(i, s); /* 生成k個檔案名f0,f1,f2,… */
        strcpy(fname[i], "f");
        strcat(fname[i], s);
        fp[i] = fopen(fname[i], "rb"); /* 以讀的方式打開檔案f0,f1,… */
        printf("有序子檔案f%d的記錄為:\n", i);
        do {
            j = fread(&r, sizeof(RedType), 1, fp[i]); /* 依次将f0,f1,…的資料讀入r */
            if (j == 1)
                print(r); /* 輸出r的内容 */
        } while (j == 1);
        printf("\n");
        rewind(fp[i]); /* 使fp[i]的指針重新傳回f0,f1,…的起始位置,以便重新讀入記憶體 */
    }
    fp[k] = fopen(fout, "wb"); /* 以寫的方式打開大檔案fout */
    K_Merge(ls, b); /* 利用敗者樹ls将k個輸入歸并段中的記錄歸并到輸出歸并段,即大檔案fout */
    for (i = 0; i <= k; i++)
        fclose(fp[i]); /* 關閉檔案f0,f1,…和檔案fout */
    fp[k] = fopen(fout, "rb"); /* 以讀的方式重新打開大檔案fout驗證排序 */
    printf("排序後的大檔案的記錄為:\n");
    i = 1;
    do {
        j = fread(&r, sizeof(RedType), 1, fp[k]); /* 将fout的資料讀入r */
        if (j == 1)
            print(r); /* 輸出r的内容 */
        if (i++ % M == 0)
            printf("\n"); /* 換行 */
    } while (j == 1);
    printf("\n");
    fclose(fp[k]); /* 關閉大檔案fout */
    return 0;
}
           
[資料結構]排序相關算法

Talk is cheap. Show me the code