数据结构之时间.空间复杂度分析

爱被打了一巴掌 2022-05-25 10:53 220阅读 0赞
  1. #include <iostream>
  2. #include <assert.h>
  3. using namespace std;
  4. /*
  5. 在很多数据结构的面试题中看似简单,但是对题目的要求却挺高,主要就体现在复杂度分析方面。复杂度又分为时间复杂度和空间复杂度。
  6. 1.时间复杂度
  7. 时间复杂度实际就是函数,函数计算执行的基本操作次数 .
  8. 在进行时间复杂度分析时需注意:
  9. 1)时间复杂度强调的是函数执行的操作次数,这里的函数是指数学里面的函数,而不是C语法里的函数;
  10. 2)在实际中我们通常情况考量的是算法的最坏情况;
  11. 3)忽略掉常数;
  12. 4) 关注运行时间的增长趋势,关注函数式中增长最快的表达式,忽略系数;
  13. (比如:F(n)=10*n^3+50n+1000,其时间复杂度为O(n)=n^3)
  14. 5)递归算法的时间复杂度计算:递归总次数*每次递归次数.
  15. 2.空间复杂度
  16. 空间复杂度,它是对一个算法在运行过程中临时占用存储空间大小的量度。所以它强调的是使用的辅助空间的的大小,而不是指所有的数据所占用的空间。
  17. 要注意的是递归算法的空间复杂度,假如递归深度为N*每次递归的辅助空间大小,如果每次递归的辅助空间为常数,则空间复杂度为O(N)。
  18. */
  19. //这是非递归的另一种算法,函数真正执行次数依然为n - 1, 所以忽略常数后,时间复杂度还是O(n);
  20. //由于采用变量交换的方式,所以在这里辅助空间个数为一个常数,空间复杂度为O(1).
  21. long long* fib(long long n)
  22. {
  23. //如果表达式的值为假,整个程序将退出,并输出一条错误信息。如果表达式的值为真则继续执行后面的语句
  24. assert(n >= 0); /*执行1次*/
  25. long long* ptr = new long long[n + 1]; /*执行1次*/
  26. ptr[0] = 0; /*执行1次*/
  27. ptr[1] = 1; /*执行1次*/
  28. for (int i = 2; i <= n; ++i) /*执行n-1次*/
  29. {
  30. ptr[i] = ptr[i - 1] + ptr[i - 2]; /*时间复杂度为O(1)的程序步骤序列*/
  31. }
  32. return ptr; /*执行n-1次*/
  33. }
  34. //递归算法的空间复杂度计算方法是:递归深度*每次递归所需的辅助空间个数.
  35. //递归栈空间(递归函数所需要的栈空间通常称为递归栈空间)包含形参a和n以及返回地址空间
  36. //对于a,需要保留一个指针(4)拿32位计算机来说,指针所占的内存空间一般为4个字节 拿64位计算机来说,指针所占的内存空间一般为8个字节
  37. //而对于n则需要保留一个int类型的值(也就是4字节) 如果返回地址也是4个字节 那么一次递归调用所需的辅助空间为12
  38. //递归深度为n+1 所以递归栈空间需要12(n+1)
  39. //SrSum = 12(n+1)=递归深度*每次递归所需的辅助空间个数.
  40. //递归算法的时间复杂度计算方法是:递归总次数*每次递归次数;
  41. template <class T>
  42. T rSum(T a[], int n) /*时间复杂度为O(n)的程序步骤序列*/
  43. {
  44. //返回数组元素a[0:n-1]的和
  45. if (n > 0)
  46. {
  47. return rSum(a, n - 1) + a[n-1];
  48. }
  49. return 0;
  50. }
  51. int main()
  52. {
  53. int a[3] = {1,2,3}; /*执行1次*/
  54. int sum = rSum(a,3); /*执行1次*/
  55. int b = sizeof(int *);
  56. system("pause");
  57. return 0;
  58. }
  59. //1)假设以最坏情况考虑,二分查找第一次在n / 2中查找(n为元素个数);第二次在一半的一半中查找,
  60. //即n / 2 / 2 = n / 4; ……第x次在n / 2 ^ x范围内查找,即2^x = n(x = log2^n), 所以时间复杂度为O(log2^n).
  61. //2)递归情况下的空间复杂度:递归深度为N*每次递归的辅助空间大小,如果每次递归的辅助空间为常数,则空间复杂度为O(N)。
  62. //对于递归的二分查找,递归深度是log2^n,每次递归的辅助空间为常数,所以空间复杂度为O(log2^N)
  63. int BinarySearch2(const int* ptr, const int x, const int left, const int right)
  64. {
  65. int mid = (left + right) / 2;
  66. while (left <= right)
  67. {
  68. if (x<ptr[mid])
  69. {
  70. return BinarySearch2(ptr, x, left, mid - 1);
  71. }
  72. else if (x>ptr[mid])
  73. {
  74. return BinarySearch2(ptr, x, mid + 1, right);
  75. }
  76. return mid;
  77. }
  78. }
  79. //对于非递归的二分查找与递归查找的时间复杂度一样的分析方法, 所以时间复杂度为O(log2^n);
  80. //但是在这个过程中,辅助空间为常数级别,所以空间复杂度为O(1)
  81. int BinarySearch1(const int* ptr, const int x, const int len)
  82. {
  83. int left = 0;
  84. int right = len - 1;
  85. int mid = (left + right) / 2;
  86. while (left <= right)
  87. {
  88. if (x<ptr[mid])
  89. {
  90. right = mid - 1;
  91. }
  92. else if (x>ptr[mid])
  93. {
  94. left = mid + 1;
  95. }
  96. else
  97. {
  98. return mid;
  99. }
  100. }
  101. return -1;
  102. }

发表评论

表情:
评论列表 (有 0 条评论,220人围观)

还没有评论,来说两句吧...

相关阅读