C语言(数组排序算法)

七、数组排序算法

选择排序

每次选择所要排序数组中最大值(从小到大排序,则选择最小值)的数组元素,将这个数组元素的值与最前面没有进行排序的数组元素的值互换。

#include <stdio.h>

/*选择排序*/
int main() {
    int i, j;
    int a[10]; /* 用于存储输入的数字 */
    int temp; /* 临时变量 */
    int pos; /* 用于存储最大元素的下标 */

    printf("为数组元素赋值:\n");
    for (int i = 0; i < 10; i++) {
        printf("a[%d]=", i);
        scanf("%d", &a[i]); /* 从标准输入读取数组元素 */
    }

    /* 从大到小排序 */
    for (int i = 0; i < 9; i++) { /* 外层循环,从第一个元素到倒数第二个元素 */
        temp = a[i]; /* 将当前位置的元素作为临时最大值 */
        pos = i;     /* 记录当前最大值的下标 */

        for (j = i + 1; j < 10; j++) { /* 内层循环,从当前位置的下一个元素开始到最后一个元素 */
            if (a[j] > temp) { /* 如果找到比当前最大值更大的元素 */
                temp = a[j]; /* 更新临时最大值 */
                pos = j;     /* 更新最大值的下标 */
            }
        }

        /* 将找到的最大值放到当前位置 */
        if (pos != i) { /* 只有当找到的最大值不是当前位置时才交换 */
            a[pos] = a[i];
            a[i] = temp;
        }
    }

    /* 输出排序后的数组 */
    for (int i = 0; i < 10; i++) {
        printf("%d\t", a[i]);
        if ((i + 1) % 5 == 0) { /* 当输出到每行的第五个元素时换行 */
            printf("\n");
        }
    }

    return 0;
}
初始数组资源	9  6  15  4  2				2和9对调
第一次排序后	2  6  15  4  9				4和6对调
第二次排序后  2  4  15  6  9				15和6对调
第三次排序后  2  4   6  15 9				15和9对调
第四次排序后  2  4   6  9  15

冒泡排序

排序时,每次比较数组中相邻的两个数组元素的值,将较小的数排在较大的数前面(从小到大排列)

#include <stdio.h>

/* 冒泡排序 */

int main() {
    int i, j;
    int a[10]; // 声明一个包含10个整数的数组
    int temp; // 用于交换元素的临时变量

    printf("为数组元素赋值:\n");
    
    /* 通过键盘为数组元素赋值 */
    for (int k = 0; k < 10; k++) {
        printf("a[%d]=", k); // 提示用户输入每个数组元素的值
        scanf("%d", &a[k]); // 将用户输入的值存入数组对应位置
    }

    /* 冒泡排序算法,从小到大排序 */
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9 - i; j++) {// 对当前未排序部分进行相邻元素比较,并交换位置,确保较大的元素逐步向右移动。
            if (a[j] > a[j + 1]) { // 如果前一个元素大于后一个元素
                temp = a[j]; // 交换两个元素
                a[j] = a[j + 1];
                a[j + 1] = temp;
            }
        }
    }

    /* 输出排序后的数组 */
    for (int k = 0; k < 10; k++) {
        printf("%d\t", a[k]); // 按顺序输出数组中的元素
        if (k == 4) {
            printf("\n"); // 在第5个元素后换行,便于显示
        }
    }

    return 0; // 返回0表示程序成功运行结束
}
初始数组资源	9  6  15   4   2
第一次排序后	2 【9  6  15   4】
第二次排序后  2  4 【9   6  15】
第三次排序后  2  4   6 【9  15】
第四次排序后  2  4   6   9  15

交换排序

交换排序是将每一位数与其后所有的数一一比较,如果发现符合条件的数据,则交换数据

#include <stdio.h>

/*交换排序*/
int main() {
    int i, j;
    int a[10];
    int temp;
    printf("为数组元素赋值:\n");
    /* 通过键盘为数组元素赋值 */
    for (int k = 0; k < 10; k++) {
        printf("a[%d]=", k); // 提示用户输入每个数组元素的值
        scanf("%d", &a[k]); // 将用户输入的值存入数组对应位置
    }
    /* 交换排序算法,从小到大排序 */
    for (int i = 0; i < 9; i++) {
        for (int j = i + 1; j < 10; j++) {
            if (a[i] > a[j]) {
                temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
        }
    }

    /* 输出排序后的数组 */
    for (int k = 0; k < 10; k++) {
        printf("%d\t", a[k]); // 按顺序输出数组中的元素
        if (k == 4) {
            printf("\n"); // 在第5个元素后换行,便于显示
        }
    }

    return 0; // 返回0表示程序成功运行结束
}
初始数组资源	【9  6   15   4    2】

第一个数字9和6比较,9大于6,交换9和6;6 9 15 4 2
6再和15比较,保持原来位置;6 9 15 4 2
6再和4比较,6大于4,交换6和4;4 9 15 6 2
4再和2比较,4大于2,交换4和2;2 9 15 6 4
第一次排序后	 2  【9  15   6    4】

第一个数字9和15比较,保持原来位置;2 9 15 6 4
9和6比较,9大于6,交换9和6;2 6 15 9 4
6和4比较,6大于4,交换6和4;2 4 15 9 6
第二次排序后   2   4  【15  9    6】

第一个数字15和9比较,15大于9,交换15和9;2 4 9 15 6
9和6比较,9大于6,交换9和6;2 4 6 15 9
第三次排序后   2   4   6   【15  9】

第一个数字15和9比较,15大于9,交换15和9;2 4 9 6 15
第四次排序后   2   4   6    9    15

插入排序

工作原理是抽出一个数据,在前面的数据中寻找相应的位置插入,直到完成排序。

  1. 将第一个数字取出来,并放置在第一个位置;

  2. 然后取出第二个数据,与第一个数据比较。

    如果第二个数字小于第一个数字,则将第二个数字排在第一个数字之前;

    否则就将第二个数字排在第一个数字之后;

  3. 接着取出下一个数字,先与排在后面的数字进行比较。

    如果当前数字比较大,则排到最后面;

    如果当前数字比较小,则还要与之前的数字进行比较,将当前数字排在比他小的数字和比他大的数字之间。

    如果没有比当前数字小的数字,则将当前数字排到最前面;

#include <stdio.h>

/*插入排序*/
int main() {
    int i, j;
    int a[10]; // 声明一个包含10个整数的数组
    int key; // 用于插入元素数据

    printf("为数组元素赋值:\n");

    /* 通过键盘为数组元素赋值 */
    for (int k = 0; k < 10; k++) {
        printf("a[%d]=", k); // 提示用户输入每个数组元素的值
        scanf("%d", &a[k]); // 将用户输入的值存入数组对应位置
    }

    /*插入排序,从小到大*/
    for (i = 1; i < 10; i++) {
        key = a[i];  // 当前要插入的元素
        j = i - 1;

        // 将比 key 大的元素都向后移动
        while (j >= 0 && a[j] > key) {
            a[j + 1] = a[j];
            j--;
        }
        a[j + 1] = key;  // 插入 key 到正确位置
    }

    /* 输出排序后的数组 */
    for (int k = 0; k < 10; k++) {
        printf("%d\t", a[k]); // 按顺序输出数组中的元素
        if (k == 4) {
            printf("\n"); // 在第5个元素后换行,便于显示
        }
    }

    return 0; // 返回0表示程序成功运行结束
}
初始数组资源	9  6  15   4   2
第一次排序后	9
第二次排序后  6  9
第三次排序后  6  9  15
第四次排序后  4  6  9  15
第四次排序后  2  4  6  9  15

折半排序

又称快速排序,二分法,工作原理是先选择一个中间值middle(在程序中使用数组中间值),然后把比中间值小的数据放在左边,把比中间值大的放在右边,最后对两边继续递归使用这个过程

#include <stdio.h>

// 二分查找item插入位置的函数
int binarySearch(int a[], int item, int low, int high) {
    // 如果范围缩小到一个元素
    if (high <= low) {
        // 如果要插入的元素大于当前元素,返回下一个位置,否则返回当前位置
        return (item > a[low]) ? (low + 1) : low;
    }

    // 计算中间位置
    int mid = (low + high) / 2;

    // 如果找到了要插入的元素,则返回它的位置
    if (item == a[mid]) {
        return mid + 1;
    }

    // 递归地在左半部分或右半部分查找
    if (item > a[mid]) {
        return binarySearch(a, item, mid + 1, high);
    }
    return binarySearch(a, item, low, mid - 1);
}

// 折半插入排序算法
void binaryInsertionSort(int a[], int n) {
    int i, loc, j, selected;

    // 从第二个元素开始插入
    for (i = 1; i < n; ++i) {
        j = i - 1;
        selected = a[i]; // 选择当前要插入的元素

        // 找到要插入的位置
        loc = binarySearch(a, selected, 0, j);

        // 移动所有大于 selected 的元素一个位置向右
        while (j >= loc) {
            a[j + 1] = a[j];
            j--;
        }
        a[j + 1] = selected; // 插入 selected 到正确的位置
    }
}

// 打印数组的函数
void printArray(int a[], int n) {
    for (int i = 0; i < n; ++i) {
        printf("%d ", a[i]);
    }
    printf("\n");
}

// 主函数
int main() {
    int a[] = {12, 11, 13, 5, 6};
    int n = sizeof(a) / sizeof(a[0]);

    printf("原始数组: ");
    printArray(a, n);

    binaryInsertionSort(a, n);

    printf("已排序数组: ");
    printArray(a, n);

    return 0;
}

初始数组资源   9    6   15   4     2     先取15
第一次排序后  【9   6    2   4】   15     再取9
第二次排序后  【6   2   4】   9    15     再取2
第三次排序后   2   【4  6】   9    15			

排序算法比较

选择排序冒泡排序交换排序插入排序折半排序,又称快速排序,二分法
每次选择所要排序数组中最大值(从小到大排序,则选择最小值)的数组元素,将这个数组元素的值与最前面没有进行排序的数组元素的值互换。排序时,每次比较数组中相邻的两个数组元素的值,将较小的数排在较大的数前面(从小到大排列)交换排序是将每一位数与其后所有的数一一比较,如果发现符合条件的数据,则交换数据工作原理是抽出一个数据,在前面的数据中寻找相应的位置插入,直到完成排序。工作原理是先选择一个中间值middle(数组中间值),然后把比中间值小的数据放在左边,把比中间值大的放在右边,最后对两边继续递归使用这个过程。
共需要进行n(n-1)/2次比较;互相交换n-1次,适用于数量较小的排序最好情况正序,比较一次即可;最坏的情况逆序,比较n^2次。稳定排序方法,排列有序时,效果好正序最快,逆序最慢。排列有序时,效果好n-1次插入过程,恰好插入末端,则不需要移动数据,可以节省时间。因此基本有序在,那么算法具有较快的运算速度。n较大时,速度最快;n较小时,慢。不稳定的,对应又相同关键字的记录,排序后的结果可能会颠倒次序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值