快速排序、归并排序、选择排序(时间复杂度、空间复杂度、实际执行时间、实际占用内存空间、每次程序迭代后的数组顺序)

#include <stdio.h>  // 引入标准输入输出头文件

#include <stdlib.h>  // 引入标准库头文件

#include <windows.h>  // 引入Windows平台头文件

#include <psapi.h>

// 给定生成随机数的个数,可修改

#define TEST_NUM 10    // 定义一个常量,表示生成随机数的个数

// ANSI 转义序列,用于改变文本颜色

#define ANSI_COLOR_GREEN "\x1b[32m"  // 定义绿色的ANSI转义序列

#define ANSI_COLOR_RESET "\x1b[0m"  // 定义重置颜色的ANSI转义序列

int quicksort_count = 0;  // 定义一个全局变量用于记录快速排序迭代次数

// 定义一个函数来获取当前时间戳(微秒级别)

double get_time() {

    LARGE_INTEGER frequency;  // 定义一个大整数结构体用于存储高精度计数器的频率

    LARGE_INTEGER start_time;  // 定义一个大整数结构体用于存储开始时间

    QueryPerformanceFrequency(&frequency);  // 获取高精度计数器的频率

    QueryPerformanceCounter(&start_time);  // 获取开始时间

    return (double)start_time.QuadPart / (double)frequency.QuadPart;  // 返回当前时间戳(微秒级别)

}

// 快速排序算法

void quicksort(int arr[], int left, int right, int size) {

    if (left < right) {

        int pivot = arr[left];  // 设置基准元素为数组的第一个元素

        int i = left;  // 定义左指针

        int j = right + 1;  // 定义右指针

        while (1) {

            do {

                i++;

            } while (arr[i] < pivot);  // 从左向右找到第一个大于等于基准元素的位置

            do {

                j--;

            } while (arr[j] > pivot);  // 从右向左找到第一个小于等于基准元素的位置

            if (i < j) {

                int temp = arr[i];

                arr[i] = arr[j];

                arr[j] = temp;  // 交换左右两个元素的位置

            }

            else {

                break;

            }

        }

        int temp = arr[left];

        arr[left] = arr[j];

        arr[j] = temp;  // 将基准元素放到正确的位置

        // 打印当前迭代后的数组顺序,并高亮打印交换的两个数

        printf("迭代 %d 次后的数组顺序: ", quicksort_count++);

        for (int k = 0; k < size; k++) {

            if (k == left || k == j) {

                printf(ANSI_COLOR_GREEN "%d " ANSI_COLOR_RESET, arr[k]);

            }

            else {

                printf("%d ", arr[k]);

            }

        }

        printf("\n");

        quicksort(arr, left, j - 1, size);  // 递归处理左边的子数组

        quicksort(arr, j + 1, right, size);  // 递归处理右边的子数组

    }

}

// 归并排序算法

void merge(int arr[], int left, int mid, int right) {

    int i, j, k;

    int n1 = mid - left + 1;  // 计算左子数组的大小

    int n2 = right - mid;  // 计算右子数组的大小

    int* L = (int*)malloc(n1 * sizeof(int));  // 为左子数组分配内存

    int* R = (int*)malloc(n2 * sizeof(int));  // 为右子数组分配内存

    for (i = 0; i < n1; i++) {

        L[i] = arr[left + i];  // 复制左半部分到临时数组L

    }

    for (j = 0; j < n2; j++) {

        R[j] = arr[mid + 1 + j];  // 复制右半部分到临时数组R

    }

    i = 0;

    j = 0;

    k = left;

    while (i < n1 && j < n2) {

        if (L[i] <= R[j]) {

            arr[k] = L[i];

            i++;

        }

        else {

            arr[k] = R[j];

            j++;

        }

        k++;

    }

    while (i < n1) {

        arr[k] = L[i];

        i++;

        k++;

    }

    while (j < n2) {

        arr[k] = R[j];

        j++;

        k++;

    }

    free(L);  // 释放临时数组L的内存

    free(R);  // 释放临时数组R的内存

    for (int k = left; k < right; k++) {

            printf("%d ", arr[k]);

    }

    printf("\n");

}

void merge_sort(int arr[], int left, int right) {

    if (left < right) {

        int mid = left + (right - left) / 2;

        merge_sort(arr, left, mid);  // 递归处理左半部分

        merge_sort(arr, mid + 1, right);  // 递归处理右半部分

        merge(arr, left, mid, right);  // 合并左右两部分

    }

}

// 选择排序算法

void selection_sort(int arr[], int n) {

    int i, j, min_idx;

    for (i = 0; i < n - 1; i++) {

        min_idx = i;

        for (j = i + 1; j < n; j++) {

            if (arr[j] < arr[min_idx]) {

                min_idx = j;

            }

        }

        int temp = arr[i];

        arr[i] = arr[min_idx];

        arr[min_idx] = temp;  // 将当前位置的元素与最小元素进行交换

        // 打印当前迭代后的数组顺序,并高亮打印交换的两个数

        printf("迭代 %d 次后的数组顺序: ", i + 1);

        for (int k = 0; k < n; k++) {

            if (k == i || k == min_idx) {

                printf(ANSI_COLOR_GREEN "%d " ANSI_COLOR_RESET, arr[k]);

            }

            else {

                printf("%d ", arr[k]);

            }

        }

        printf("\n");

    }

}

// 填充随机测试数组

void random_add(int arr1[], int arr2[], int arr3[], int size) {

    for (int i = 0; i < size; i++) {

        arr1[i] = rand() % 1000000000; // 随机数范围0 ≤ x < 10^9

        arr2[i] = arr1[i]; // 复制到arr2

        arr3[i] = arr1[i]; // 复制到arr3

    }

    for (int i = 0; i < size; i++) {

        printf("%d ", arr1[i]); // 打印随机数

    }

}

 //定义printMemoryInfo函数来打印内存使用信息

void printMemoryInfo(HANDLE process) {

    PROCESS_MEMORY_COUNTERS_EX pmc;

    if (GetProcessMemoryInfo(process, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) {

        printf("私有工作集: %llu 字节\n", (ULONGLONG)pmc.PrivateUsage);

        printf("共享工作集: %llu 字节\n", (ULONGLONG)(pmc.WorkingSetSize - pmc.PrivateUsage));

        printf("虚拟内存大小: %llu 字节\n", (ULONGLONG)pmc.PagefileUsage);

    }

}

int main() {

    int arr1[TEST_NUM];

    int arr2[TEST_NUM];

    int arr3[TEST_NUM];

    int size = sizeof(arr1) / sizeof(arr1[0]);

    printf("随机生成的数组如下:\n");

    random_add(arr1, arr2, arr3, size);

    // 快速排序

    printf("\n快速排序:\n");

    double start, end;

    start = get_time();

    // 在排序之前获取和打印内存使用情况

    /*printf("排序前:\n");

    PROCESS_MEMORY_COUNTERS_EX pmc;

    if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) {

        printf("私有工作集: %llu 字节\n", (ULONGLONG)pmc.PrivateUsage);

        printf("共享工作集: %llu 字节\n", (ULONGLONG)(pmc.WorkingSetSize - pmc.PrivateUsage));

        printf("虚拟内存大小: %llu 字节\n", (ULONGLONG)pmc.PagefileUsage);

    }*/

    quicksort(arr1, 0, size - 1, size);

    // 在排序之后获取和打印内存使用情况

    /*printf("排序后:\n");

    if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) {

        printf("私有工作集: %llu 字节\n", (ULONGLONG)pmc.PrivateUsage);

        printf("共享工作集: %llu 字节\n", (ULONGLONG)(pmc.WorkingSetSize - pmc.PrivateUsage));

        printf("虚拟内存大小: %llu 字节\n", (ULONGLONG)pmc.PagefileUsage);

    }*/

    end = get_time();

    printf("运行时间: %lf seconds\n", (double)(end - start));

    // 归并排序

    printf("\n归并排序:\n");

    start = get_time();

    ///在排序之前获取和打印内存使用情况

    /*printf("排序前:\n");

    if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) {

        printf("私有工作集: %llu 字节\n", (ULONGLONG)pmc.PrivateUsage);

        printf("共享工作集: %llu 字节\n", (ULONGLONG)(pmc.WorkingSetSize - pmc.PrivateUsage));

        printf("虚拟内存大小: %llu 字节\n", (ULONGLONG)pmc.PagefileUsage);

    }*/

    merge_sort(arr2, 0, size - 1);

    // 在排序之后获取和打印内存使用情况

    /*printf("排序后:\n");

    if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) {

        printf("私有工作集: %llu 字节\n", (ULONGLONG)pmc.PrivateUsage);

        printf("共享工作集: %llu 字节\n", (ULONGLONG)(pmc.WorkingSetSize - pmc.PrivateUsage));

        printf("虚拟内存大小: %llu 字节\n", (ULONGLONG)pmc.PagefileUsage);

    }*/

    end = get_time();

    printf("运行时间: %lf seconds\n", (double)(end - start));

    // 选择排序

    printf("\n选择排序:\n");

    start = get_time();

    ///在排序之前获取和打印内存使用情况

    /*printf("排序前:\n");

    if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) {

        printf("私有工作集: %llu 字节\n", (ULONGLONG)pmc.PrivateUsage);

        printf("共享工作集: %llu 字节\n", (ULONGLONG)(pmc.WorkingSetSize - pmc.PrivateUsage));

        printf("虚拟内存大小: %llu 字节\n", (ULONGLONG)pmc.PagefileUsage);

    }*/

    selection_sort(arr3, size);

    // 在排序之后获取和打印内存使用情况

    /*printf("排序后:\n");

    if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) {

        printf("私有工作集: %llu 字节\n", (ULONGLONG)pmc.PrivateUsage);

        printf("共享工作集: %llu 字节\n", (ULONGLONG)(pmc.WorkingSetSize - pmc.PrivateUsage));

        printf("虚拟内存大小: %llu 字节\n", (ULONGLONG)pmc.PagefileUsage);

    }*/

    end = get_time();

    printf("运行时间: %lf seconds\n", (double)(end - start));

    return 0;

}

  1. 输入随机生成0x≦109数组,长度分别为5、10、100;

5:

10:

100:

  1. 时间复杂度、空间复杂度、实际执行时间、实际占用内存空间

快速排序(Quick Sort):

时间复杂度:

最优情况:O(n log n)

平均情况:O(n log n)

最坏情况:O(n^2)(当数组已经有序时)

空间复杂度:

最优情况:O(log n)(递归调用栈的深度)

最坏情况:O(n)(当数组已经有序时)

归并排序(Merge Sort):

时间复杂度:

最优情况:O(n log n)

平均情况:O(n log n)

最坏情况:O(n log n)

空间复杂度:

总体空间复杂度为O(n),但是因为归并排序是基于分治法的,所以它需要额外的空间来存储临时数组,因此空间复杂度为O(n)。

选择排序(Selection Sort):

时间复杂度:

最优情况:O(n^2)

平均情况:O(n^2)

最坏情况:O(n^2)

空间复杂度:

O(1)(不需要额外的空间,只需要交换元素的位置)

实际执行时间、实际占用内存空间以10长度为例:

  1. 每次程序迭代后的数组顺序

    研究与思考:分析算法时间复杂性,能否将递归程序非递归化?

    快速排序的非递归版本:

    时间复杂度:

    最优情况:O(n log n)

    平均情况:O(n log n)

    最坏情况:O(n^2)(当数组已经有序时)

    空间复杂度:

    最优情况:O(log n)(栈空间用于存储分割点)

    最坏情况:O(n)(当数组已经有序时)

    归并排序的非递归版本:

    时间复杂度:

    最优情况:O(n log n)

    平均情况:O(n log n)

    最坏情况:O(n log n)

    空间复杂度:

    总体空间复杂度为O(n),但因为归并排序需要额外的空间来存储临时数组,所以空间复杂度为O(n)。

    选择排序:

    选择排序本身就是一个迭代算法,不需要进行递归化。其时间复杂度和空间复杂度如下:

    时间复杂度:

    最优情况:O(n^2)

    平均情况:O(n^2)

    最坏情况:O(n^2)

    空间复杂度:

    O(1)(不需要额外的空间,只需要交换元素的位置)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
快速排序: 最好时间复杂度:O(nlogn) 最坏时间复杂度:O(n²) 平均时间复杂度:O(nlogn) 空间复杂度:O(logn) ```python def quick_sort(arr): if len(arr) <= 1: return arr pivot = arr[len(arr) // 2] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quick_sort(left) + middle + quick_sort(right) ``` 堆排序: 最好时间复杂度:O(nlogn) 最坏时间复杂度:O(nlogn) 平均时间复杂度:O(nlogn) 空间复杂度:O(1) ```python def heapify(arr, n, i): largest = i l = 2 * i + 1 r = 2 * i + 2 if l < n and arr[i] < arr[l]: largest = l if r < n and arr[largest] < arr[r]: largest = r if largest != i: arr[i], arr[largest] = arr[largest], arr[i] heapify(arr, n, largest) def heap_sort(arr): n = len(arr) for i in range(n // 2 - 1, -1, -1): heapify(arr, n, i) for i in range(n - 1, 0, -1): arr[i], arr[0] = arr[0], arr[i] heapify(arr, i, 0) return arr ``` 归并排序: 最好时间复杂度:O(nlogn) 最坏时间复杂度:O(nlogn) 平均时间复杂度:O(nlogn) 空间复杂度:O(n) ```python def merge_sort(arr): if len(arr) <= 1: return arr mid = len(arr) // 2 left = merge_sort(arr[:mid]) right = merge_sort(arr[mid:]) return merge(left, right) def merge(left, right): result = [] i = j = 0 while i < len(left) and j < len(right): if left[i] < right[j]: result.append(left[i]) i += 1 else: result.append(right[j]) j += 1 result += left[i:] result += right[j:] return result ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值