IT评测·应用市场-qidao123.com

标题: 从C语言看数据结构和算法:复杂度决定性能 [打印本页]

作者: 祗疼妳一个    时间: 2025-1-23 10:40
标题: 从C语言看数据结构和算法:复杂度决定性能
大家好,这里是小编的博客频道
小编的博客:就爱学编程
    很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同劳绩更好的本身!!!
  
  
引言

在计算机科学中,算法是解决问题的核心工具。当我们计划或选择一个算法时,通常需要考虑两个关键因素:时间复杂度和空间复杂度。这两个指标帮助我们权衡算法的服从和资源斲丧情况。本文将深入探究C语言中常见的数据结构及其相关算法的复杂度分析,并通过代码示例进行具体阐明。那现在,一起来看看吧!!!


   那接下来就让我们开始遨游在知识的海洋!
  正文


一 时间复杂度

   
  
1. 常数时间复杂度 O(1)

   
  例:
  1. #include <stdio.h>
  2. int getElement(int arr[], int index, int size) {
  3.     if (index >= 0 && index < size) {
  4.         return arr[index]; // 直接访问数组元素,时间复杂度为O(1)
  5.     } else {
  6.         return -1; // 错误处理
  7.     }
  8. }
  9. int main() {
  10.     int arr[] = {1, 2, 3, 4, 5};
  11.     printf("%d
  12. ", getElement(arr, 2, 5)); // 输出3
  13.     return 0;
  14. }
复制代码

2. 线性时间复杂度 O(n)

   
  例·:
  1. #include <stdio.h>
  2. void printArray(int arr[], int size) {
  3.     for (int i = 0; i < size; i++) {
  4.         printf("%d ", arr[i]); // 遍历数组,时间复杂度为O(n)
  5.     }
  6.     printf("
  7. ");
  8. }
  9. int main() {
  10.     int arr[] = {1, 2, 3, 4, 5};
  11.     printArray(arr, 5); // 输出整个数组
  12.     return 0;
  13. }
复制代码

3. 对数时间复杂度 O(log n)

   
  例·:
  1. #include <stdio.h>
  2. int binarySearch(int arr[], int target, int left, int right) {
  3.     while (left <= right) {
  4.         int mid = left + (right - left) / 2;
  5.         if (arr[mid] == target) {
  6.             return mid; // 找到目标,返回索引
  7.         } else if (arr[mid] < target) {
  8.             left = mid + 1; // 在右半部分继续搜索
  9.         } else {
  10.             right = mid - 1; // 在左半部分继续搜索
  11.         }
  12.     }
  13.     return -1; // 未找到目标
  14. }
  15. int main() {
  16.     int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  17.     int target = 7;
  18.     int result = binarySearch(arr, target, 0, 9);
  19.     if (result != -1) {
  20.         printf("Found %d at index %d
  21. ", target, result);
  22.     } else {
  23.         printf("%d not found in array
  24. ", target);
  25.     }
  26.     return 0;
  27. }
复制代码

4. 平方时间复杂度 O(n^2)

   
  冒泡排序示例:
  1. #include <stdio.h>
  2. void bubbleSort(int arr[], int size) {
  3.     for (int i = 0; i < size - 1; i++) {
  4.         for (int j = 0; j < size - i - 1; j++) {
  5.             if (arr[j] > arr[j + 1]) {
  6.                 // 交换元素
  7.                 int temp = arr[j];
  8.                 arr[j] = arr[j + 1];
  9.                 arr[j + 1] = temp;
  10.             }
  11.         }
  12.     }
  13. }
  14. void printArray(int arr[], int size) {
  15.     for (int i = 0; i < size; i++) {
  16.         printf("%d ", arr[i]);
  17.     }
  18.     printf("
  19. ");
  20. }
  21. int main() {
  22.     int arr[] = {64, 34, 25, 12, 22, 11, 90};
  23.     int size = sizeof(arr)/sizeof(arr[0]);
  24.     bubbleSort(arr, size);
  25.     printf("Sorted array:
  26. ");
  27.     printArray(arr, size);
  28.     return 0;
  29. }
复制代码

5. 指数时间复杂度 O(2^n)

   
  1. // 未经优化的斐波那契数列计算
  2. #include <stdio.h>
  3. int fibonacci(int n) {
  4.     if (n <= 1) {
  5.         return n;
  6.     } else {
  7.         return fibonacci(n - 1) + fibonacci(n - 2);
  8.     }
  9. }
  10. int main() {
  11.     int n = 10;
  12.     printf("Fibonacci number is %d
  13. ", fibonacci(n));
  14.     return 0;
  15. }
复制代码

二 空间复杂度

(1)空间复杂度的定义与紧张性

   
  
(2)常见的空间复杂度范例及介绍

1.常数空间复杂度 O(1)

   
  比方,一个简朴的交换两个整数值的函数:
  1. #include <stdio.h>
  2. void swap(int *a, int *b) {
  3.     int temp = *a;
  4.     *a = *b;
  5.     *b = temp;
  6. }
  7. int main() {
  8.     int x = 5, y = 10;
  9.     swap(&x, &y);
  10.     printf("x = %d, y = %d
  11. ", x, y); // 输出: x = 10, y = 5
  12.     return 0;
  13. }
复制代码
在这个例子中,swap 函数只利用了一个额外的变量 temp 来存储临时值,因此它的空间复杂度是 O(1)。

2.线性空间复杂度 O(n)

   
  比方,一个计算数组中所有元素之和的函数:
  1. #include <stdio.h>
  2. int sumArray(int arr[], int size) {
  3.     int sum = 0;
  4.     for (int i = 0; i < size; i++) {
  5.         sum += arr[i];
  6.     }
  7.     return sum;
  8. }
  9. int main() {
  10.     int arr[] = {1, 2, 3, 4, 5};
  11.     int size = sizeof(arr) / sizeof(arr[0]);
  12.     printf("Sum = %d
  13. ", sumArray(arr, size)); // 输出: Sum = 15
  14.     return 0;
  15. }
复制代码
这里,除了几个固定巨细的变量(如 sum 和循环计数器 i)外,没有利用额外的内存。但是,由于我们假设数组本身占用的空间也计入空间复杂度(尽管它是作为输入提供的),所以整个步伐的空间复杂度可以视为 O(n)(此中 n 是数组的巨细)。然而,仅就 sumArray 函数而言,其额外利用的空间仍旧是 O(1)。

3.多项式空间复杂度 O(n^k)(k为常数)

   
  
比方,打印一个 n×n 矩阵的元素:
  1. #include <stdio.h>
  2. void printMatrix(int matrix[][10], int n) {
  3.     for (int i = 0; i < n; i++) {
  4.         for (int j = 0; j < n; j++) {
  5.             printf("%d ", matrix[i][j]);
  6.         }
  7.         printf("
  8. ");
  9.     }
  10. }
  11. int main() {
  12.     int matrix[10][10] = { /* 初始化矩阵 */ };
  13.     // 假设矩阵已经以某种方式被填充
  14.     printMatrix(matrix, 10); // 这里 n 被硬编码为 10,但一般情况下可以是任何正整数
  15.     return 0;
  16. }
复制代码
注意:


4. 动态分配的内存(可变空间复杂度)

当利用 malloc、calloc 或 realloc 等函数动态分配内存时,空间复杂度可能变得不那么直观。它取决于运行时决定分配的内存量。比方:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. void createAndFillArray(int **array, int size) {
  4.     *array = (int *)malloc(size * sizeof(int));
  5.     if (*array == NULL) {
  6.         fprintf(stderr, "Memory allocation failed
  7. ");
  8.         exit(EXIT_FAILURE);
  9.     }
  10.     for (int i = 0; i < size; i++) {
  11.         (*array)[i] = i * i; // 例如,用平方值填充数组
  12.     }
  13. }
  14. int main() {
  15.     int size = 100; // 可以根据需要改变大小
  16.     int *array = NULL;
  17.     createAndFillArray(&array, size);
  18.     // 使用数组...
  19.     free(array); // 不要忘记释放分配的内存!
  20.     return 0;
  21. }
复制代码
在这个例子中,createAndFillArray 函数根据传入的 size 参数动态分配一个整数数组。因此,该函数的空间复杂度是 O(size),即 O(n)(假如我们将 size 视为输入 n参数)。注意,这里的空间复杂度是指除了输入参数和固定巨细的变量之外额外分配的内存量。

(3)空间复杂度的分析方法

分析算法的空间复杂度时,需要考虑以下几个方面:
   
   
   
  综上所述:


三 空间复杂度与时间复杂度的关系

   
  
四 常见算法的复杂度分析

1. 线性搜索

   
  代码展示:
  1. #include <stdio.h>
  2. int linearSearch(int arr[], int size, int target) {
  3.     for (int i = 0; i < size; i++) {
  4.         if (arr[i] == target) {
  5.             return i; // 找到目标值,返回索引
  6.         }
  7.     }
  8.     return -1; // 未找到目标值,返回-1
  9. }
  10. int main() {
  11.     int arr[] = {2, 4, 6, 8, 10};
  12.     int target = 6;
  13.     int result = linearSearch(arr, 5, target);
  14.     if (result != -1) {
  15.         printf("Element found at index %d
  16. ", result);
  17.     } else {
  18.         printf("Element not found in the array
  19. ");
  20.     }
  21.     return 0;
  22. }
复制代码


2. 二分搜索

   
  代码展示:
  1. #include <stdio.h>
  2. int binarySearch(int arr[], int size, int target) {
  3.     int left = 0, right = size - 1;
  4.     while (left <= right) {
  5.         int mid = left + (right - left) / 2;
  6.         if (arr[mid] == target) {
  7.             return mid; // 找到目标值,返回索引
  8.         } else if (arr[mid] < target) {
  9.             left = mid + 1; // 在右半部分继续搜索
  10.         } else {
  11.             right = mid - 1; // 在左半部分继续搜索
  12.         }
  13.     }
  14.     return -1; // 未找到目标值,返回-1
  15. }
  16. int main() {
  17.     int arr[] = {2, 4, 6, 8, 10};
  18.     int target = 6;
  19.     int result = binarySearch(arr, 5, target);
  20.     if (result != -1) {
  21.         printf("Element found at index %d
  22. ", result);
  23.     } else {
  24.         printf("Element not found in the array
  25. ");
  26.     }
  27.     return 0;
  28. }
复制代码


3. 冒泡排序

   冒泡排序是一种简朴的排序算法,通过重复遍历要排序的数列,一次比较两个元素,假如它们的次序错误就把它们交换过来。遍历数列的工作是重复进行的,直到没有再需要交换的元素为止。
  1. #include <stdio.h>
  2. void bubbleSort(int arr[], int size) {
  3.     for (int i = 0; i < size - 1; i++) {
  4.         for (int j = 0; j < size - i - 1; j++) {
  5.             if (arr[j] > arr[j + 1]) {
  6.                 // 交换arr[j]和arr[j+1]
  7.                 int temp = arr[j];
  8.                 arr[j] = arr[j + 1];
  9.                 arr[j + 1] = temp;
  10.             }
  11.         }
  12.     }
  13. }
  14. void printArray(int arr[], int size) {
  15.     for (int i = 0; i < size; i++) {
  16.         printf("%d ", arr[i]);
  17.     }
  18.     printf("
  19. ");
  20. }
  21. int main() {
  22.     int arr[] = {64, 34, 25, 12, 22, 11, 90};
  23.     int size = sizeof(arr) / sizeof(arr[0]);
  24.     bubbleSort(arr, size);
  25.     printf("Sorted array:
  26. ");
  27.     printArray(arr, size);
  28.     return 0;
  29. }
复制代码


快乐的时光总是短暂,咱们下篇博文再见啦!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4