• 数据结构与算法基础-学习-34-基数排序(桶排序)


    目录

    一、基本思想

    二、算法思路

    1、个位排序

    (1)分配

    (2)收集

    2、十分位排序

    (1)分配

    (2)收集

    三、源码分享

    1、InitMyBucket

    2、DestroyMyBucket

    3、ClearMyBucket

    4、PushData2Bucket

    5、PopDataFromBucket

    6、GetIntegerDigit

    7、BucketSortSentryQueue

    四、算法效率

    五、Linux环境编译测试


    排序的其他相关知识点和源码分享可以参考之前的博客:   

    数据结构与算法基础-学习-30-插入排序之直接插入排序、二分插入排序、希尔排序》,

    数据结构与算法基础-学习-31-交换排序之冒泡排序、快速排序》,

    数据结构与算法基础-学习-32-选择排序之简单选择排序、堆排序》,

    数据结构与算法基础-学习-33-归并排序

    一、基本思想

    基数排序的基本思想就是分配和收集。

    基数排序也叫桶排序、箱排序,设置若干个桶,将关键字为k的记录放入第k个桶,然后再按照序号将非空的连接。

    二、算法思路

    我们还是以升序为例,初始化10个桶来存放数据,因为上面的数据最多到十分位,我们只需要两部就可以完成排序。

    1、个位排序

    (1)分配

    10的个位是0,放到0号桶。

    34的个位是4,放到4号桶。

    1的个位是1,放到1号桶。

    后面的数据以此类推。

    (2)收集

    我们按照顺序从第0个桶、第1个桶。。。。的顺序取数据,可以发现个位已经有序。并且只有个位的元素就不需要进行下一轮十分位的排序,我们只用比较有十分位的元素,这样可以减少排序时间。收集前桶中数据是全部,为了效率我们可以直接把只有个位的放入原序列中。

    2、十分位排序

    (1)分配

    我们清空桶,将临时队列中的元素按照十分位的数值放入桶中。

    (2)收集

    我们按照顺序从第0个桶、第1个桶。。。。的顺序取数据,由于这些元素只有最大十分位,我们可以直接放入原队列中,这样就排好序啦。

    三、源码分享

    1、InitMyBucket

    1. Status InitMyBucket(MyBucket** Bucket, QueueLenType BucketGroupNums, QueueLenType OneBucketNums, JudgeTypeFlag Flag)
    2. {
    3. JudgeAllNullPointer(Bucket);
    4. if (BucketGroupNums * OneBucketNums > __LONG_LONG_MAX__)
    5. {
    6. LogFormat(Error,"Init Bucket Fail, Reason : BucketGroupNums(%lld) * OneBucketNums(%lld) > %lld.\n",
    7. BucketGroupNums,OneBucketNums,__LONG_LONG_MAX__);
    8. return FailFlag;
    9. }
    10. QueueLenType i;
    11. (*Bucket) = (MyBucket*)MyMalloc(sizeof(MyBucket));
    12. (*Bucket)->BucketArrayMaxLen = BucketGroupNums;
    13. (*Bucket)->BucketDataUseNums = 0;
    14. (*Bucket)->BucketDataMaxUseNums = BucketGroupNums * OneBucketNums;
    15. (*Bucket)->BucketArray = (SqQueue**)MyMalloc(BucketGroupNums * sizeof(SqQueue*));
    16. for ( i = 0; i < (*Bucket)->BucketArrayMaxLen; i++)
    17. {
    18. InitSqQueue(&((*Bucket)->BucketArray[i]),OneBucketNums,Flag);
    19. }
    20. LogFormat(Debug,"Init Bucket OK.\n");
    21. return SuccessFlag;
    22. }

    2、DestroyMyBucket

    1. Status DestroyMyBucket(MyBucket** Bucket)
    2. {
    3. JudgeAllNullPointer(*Bucket);
    4. QueueLenType i;
    5. for ( i = 0; i < (*Bucket)->BucketArrayMaxLen; i++)
    6. {
    7. DestroySqQueue(&((*Bucket)->BucketArray[i]));
    8. }
    9. free((*Bucket)->BucketArray);
    10. (*Bucket)->BucketArray = NULL;
    11. (*Bucket)->BucketArrayMaxLen = 0;
    12. (*Bucket)->BucketDataUseNums = 0;
    13. (*Bucket)->BucketDataMaxUseNums = 0;
    14. free(*Bucket);
    15. *Bucket = NULL;
    16. LogFormat(Debug,"Destroy Bucket OK.\n");
    17. return SuccessFlag;
    18. }

    3、ClearMyBucket

    1. Status ClearMyBucket(MyBucket* Bucket)
    2. {
    3. JudgeAllNullPointer(Bucket);
    4. QueueLenType i;
    5. for ( i = 0; i < Bucket->BucketArrayMaxLen; i++)
    6. {
    7. ClearSqQueue(Bucket->BucketArray[i]);
    8. }
    9. Bucket->BucketDataUseNums = 0;
    10. LogFormat(Debug,"Clear Bucket OK.\n");
    11. return SuccessFlag;
    12. }

    4、PushData2Bucket

    1. //将数据压入桶中。
    2. Status PushData2Bucket(MyBucket* Bucket, QueueLenType BucketGroupIndex, void* Data)
    3. {
    4. JudgeAllNullPointer(Bucket);
    5. JudgeAllNullPointer(Data);
    6. if (BucketGroupIndex < 0 || BucketGroupIndex >= Bucket->BucketArrayMaxLen)
    7. {
    8. LogFormat(Error,"Push Data To Bucket Fail, Reason : Illegal BucketGroupIndex(%lld).\n",BucketGroupIndex);
    9. return FailFlag;
    10. }
    11. if (Bucket->BucketDataUseNums == Bucket->BucketDataMaxUseNums)
    12. {
    13. LogFormat(Warning,"Push Data To Bucket Fail, Reason : Bucket Is Full(%lld).\n",Bucket->BucketDataMaxUseNums);
    14. return NormalFlag;
    15. }
    16. Status ReturnStatus;
    17. ReturnStatus = EnterSqQueue(Bucket->BucketArray[BucketGroupIndex],Data);
    18. if (ReturnStatus == SuccessFlag)
    19. {
    20. Bucket->BucketDataUseNums++;
    21. LogFormat(Debug,"Push Data To Bucket OK.\n");
    22. }
    23. return ReturnStatus;
    24. }

    5、PopDataFromBucket

    1. //将数据从桶中取出来。
    2. Status PopDataFromBucket(MyBucket* Bucket, QueueLenType BucketGroupIndex, void* Data)
    3. {
    4. JudgeAllNullPointer(Bucket);
    5. JudgeAllNullPointer(Data);
    6. if (BucketGroupIndex < 0 || BucketGroupIndex >= Bucket->BucketArrayMaxLen)
    7. {
    8. LogFormat(Error,"Pop Data From Bucket Fail, Reason : Illegal BucketGroupIndex(%lld).\n",BucketGroupIndex);
    9. return FailFlag;
    10. }
    11. if (Bucket->BucketDataUseNums == 0)
    12. {
    13. LogFormat(Warning,"Pop Data From Bucket Fail, Reason : Bucket Is Empty.\n");
    14. return NormalFlag;
    15. }
    16. Status ReturnStatus;
    17. ReturnStatus = LeaveSqQueue(Bucket->BucketArray[BucketGroupIndex],Data);
    18. if (ReturnStatus == SuccessFlag)
    19. {
    20. Bucket->BucketDataUseNums--;
    21. LogFormat(Debug,"Pop Data From Bucket OK.\n");
    22. }
    23. return ReturnStatus;
    24. }

    6、GetIntegerDigit

    1. //给出一个正整数,和你想要的位数,返回相应的位数。
    2. //例如1234,你要十分位,返回一个3。
    3. //1表示个位,2表示十分位,以此类推。
    4. //目前只支持int类型
    5. int GetIntegerDigit(int Num, int Digit)
    6. {
    7. // LogFormat(Debug,"Num : %d, Digit : %d\n",Num,Digit);
    8. if (Digit < 1 || Digit > 9)
    9. {
    10. return GET_INTEGER_DIGIT_FAIL_FLAG;
    11. }
    12. if (Num < 0)
    13. {
    14. return GET_INTEGER_DIGIT_FAIL_FLAG;
    15. }
    16. if (Digit == 1)
    17. {
    18. return Num % 10;
    19. }
    20. else if (MyIntSquare(10,Digit - 1) > Num)//如果Num不存在Digit相应的位数,如89不存在百分位的情况。
    21. {
    22. return GET_INTEGER_DIGIT_NO_EXISTS_FLAG;
    23. }
    24. else
    25. {
    26. return (Num % MyIntSquare(10,Digit) - Num % MyIntSquare(10,Digit - 1)) / MyIntSquare(10,Digit - 1);
    27. }
    28. }

    7、BucketSortSentryQueue

    1. //由于GetIntegerDigit实现的原因,导致BucketSortSentryQueue只支持正整数排序。
    2. //此函数如果执行出错,会改变Queue的值,里面存了中间结果。
    3. Status BucketSortSentryQueue(SqQueue* Queue)
    4. {
    5. JudgeAllNullPointer(Queue);
    6. MyBucket* Bucket = NULL;
    7. SqQueue* TmpQueue = NULL;//临时队列,存放中间数据。
    8. switch(Queue->Flag)
    9. {
    10. case INT_TYPE_FLAG :
    11. InitMyBucket(&Bucket,INTEGER_BUCKET_NUMS,Queue->SqQueueLen,Queue->Flag);
    12. InitSqQueue(&TmpQueue,Queue->SqQueueLen,Queue->Flag);
    13. break;
    14. default :
    15. LogFormat(Error,"BucketSortSentry Function , Queue->Flag(%d) Is Unknow Type Flag, Exit!!!\n",Queue->Flag);
    16. exit(ExceptionExitFlag);
    17. }
    18. //后续再做成万能数据型
    19. //现在只支持整型
    20. int ReutrnVal = 0;
    21. QueueLenType i;
    22. QueueLenType BucketGroupIndex = 0;
    23. Status ReturnStatus;
    24. int Digit = 1;//计算的位数
    25. QueueLenType MaxQueueLen = Queue->SqQueueLen;
    26. do
    27. {
    28. if (Digit != 1)
    29. {
    30. //第n次收集是从TmpQueue读取数据,做整数Digit位的排序,放入桶中。
    31. for ( i = 0; i < TmpQueue->SqQueueLen; i++)
    32. {
    33. ReadSqQueue(TmpQueue,i,&ReutrnVal);
    34. BucketGroupIndex = GetIntegerDigit(ReutrnVal,Digit);
    35. PushData2Bucket(Bucket, BucketGroupIndex, &ReutrnVal);
    36. }
    37. //清理临时队列。
    38. ClearSqQueue(TmpQueue);
    39. }
    40. else
    41. {
    42. //第一次收集是从传入参数Queue读取数据,做整数个位的排序,放入桶中。
    43. for ( i = 1; i < Queue->SqQueueLen; i++)
    44. {
    45. ReadSqQueue(Queue,i,&ReutrnVal);
    46. BucketGroupIndex = GetIntegerDigit(ReutrnVal,Digit);
    47. PushData2Bucket(Bucket, BucketGroupIndex, &ReutrnVal);
    48. }
    49. ReadSqQueue(Queue,0,&ReutrnVal);
    50. ClearSqQueue(Queue);
    51. EnterSqQueue(Queue,&ReutrnVal);
    52. }
    53. //第n次分配,从桶中把顺序数据读取出来。
    54. i = 0;
    55. Digit++;
    56. while (Bucket->BucketDataUseNums != 0)
    57. {
    58. ReturnStatus = PopDataFromBucket(Bucket, i, &ReutrnVal);
    59. if (ReturnStatus == SuccessFlag)//成功读出数据,放入临时队列中。
    60. {
    61. if (GetIntegerDigit(ReutrnVal,Digit) == GET_INTEGER_DIGIT_NO_EXISTS_FLAG)//如果给的数没有Digit,放到最终队列中。
    62. {
    63. EnterSqQueue(Queue,&ReutrnVal);
    64. }
    65. else if (GetIntegerDigit(ReutrnVal,Digit) != GET_INTEGER_DIGIT_FAIL_FLAG)//有Digit的进行下一步计算。
    66. {
    67. EnterSqQueue(TmpQueue,&ReutrnVal);
    68. }
    69. else//异常情况
    70. {
    71. LogFormat(Error,"Bucket Sort Sentry Queue Fail, Reason : Error Data(%d).\n",ReutrnVal);
    72. exit(ExceptionExitFlag);
    73. }
    74. }
    75. else if (ReturnStatus == NormalFlag)//由于第i个桶的数据被读取完了,读下一个桶。
    76. {
    77. i++;
    78. }
    79. else//读取数据失败
    80. {
    81. DestroyMyBucket(&Bucket);
    82. DestroySqQueue(&TmpQueue);
    83. Bucket = NULL;
    84. TmpQueue = NULL;
    85. LogFormat(Error,"Bucket Sort Sentry Queue Fail, Reason : Pop Data From Bucket Fail.\n");
    86. return FailFlag;
    87. }
    88. }
    89. //清理桶
    90. ClearMyBucket(Bucket);
    91. }while (GetSqQueueLen(Queue) < MaxQueueLen);//如果最终结果队列的元素个数小于Queue队列的元素个数,说明数据没有排序完。
    92. DestroyMyBucket(&Bucket);
    93. DestroySqQueue(&TmpQueue);
    94. Bucket = NULL;
    95. TmpQueue = NULL;
    96. LogFormat(Debug,"Bucket Sort Sentry Queue OK.\n");
    97. return SuccessFlag;
    98. }

    四、算法效率

    情况时间复杂度是否稳定
    最好O(n + m)稳定
    最坏O(k * (n + m))
    平均O(k * (n + m))

    例如我们上面这个计算时间复杂度是多少呢?

     (10个数字 + 10个桶)* 2位数 = 40

    五、Linux环境编译测试

    1. [gbase@czg2 Sort]$ make
    2. gcc -Wall -Wextra -O3 InsertSort.c SwapSort.c SelectSort.c MergeSort.c BucketSort.c main.c -o TestSort -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/Log/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/HashTable/include/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/SqQueue/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/SqStack/ -L /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Make/Libs/ -lPublicFunction -lLog -lSqQueue
    3. [gbase@czg2 Sort]$ time ./TestSort
    4. 2023-9-12--[ Debug ]--Init SqQueue OK
    5. 2023-9-12--[ Debug ]--Enter SqQueue OK
    6. 2023-9-12--[ Debug ]--Enter SqQueue OK
    7. 2023-9-12--[ Debug ]--Enter SqQueue OK
    8. 2023-9-12--[ Debug ]--Enter SqQueue OK
    9. 2023-9-12--[ Debug ]--Enter SqQueue OK
    10. 2023-9-12--[ Debug ]--Enter SqQueue OK
    11. 2023-9-12--[ Debug ]--Enter SqQueue OK
    12. 2023-9-12--[ Debug ]--Enter SqQueue OK
    13. 2023-9-12--[ Debug ]--Enter SqQueue OK
    14. 2023-9-12--[ Debug ]--Enter SqQueue OK
    15. 2023-9-12--[ Debug ]--Enter SqQueue OK
    16. 2023-9-12--[ Info ]--SqQueue Data :
    17. Data : [ 0 ,5 ,6 ,7 ,8 ,9 ,0 ,1 ,2 ,3 ,4 ]
    18. FrontIndex : 0
    19. RearIndex : 0
    20. SqQueueLen : 11
    21. SqQueueMaxLen : 11
    22. Flag : INT_TYPE_FLAG
    23. 2023-9-12--[ Debug ]--Init SqQueue OK
    24. 2023-9-12--[ Debug ]--Init SqQueue OK
    25. 2023-9-12--[ Debug ]--Init SqQueue OK
    26. 2023-9-12--[ Debug ]--Init SqQueue OK
    27. 2023-9-12--[ Debug ]--Init SqQueue OK
    28. 2023-9-12--[ Debug ]--Init SqQueue OK
    29. 2023-9-12--[ Debug ]--Init SqQueue OK
    30. 2023-9-12--[ Debug ]--Init SqQueue OK
    31. 2023-9-12--[ Debug ]--Init SqQueue OK
    32. 2023-9-12--[ Debug ]--Init SqQueue OK
    33. 2023-9-12--[ Debug ]--Init Bucket OK.
    34. 2023-9-12--[ Debug ]--Init SqQueue OK
    35. 2023-9-12--[ Debug ]--Read SqQueue OK
    36. 2023-9-12--[ Debug ]--Enter SqQueue OK
    37. 2023-9-12--[ Debug ]--Push Data To Bucket OK.
    38. 2023-9-12--[ Debug ]--Read SqQueue OK
    39. 2023-9-12--[ Debug ]--Enter SqQueue OK
    40. 2023-9-12--[ Debug ]--Push Data To Bucket OK.
    41. 2023-9-12--[ Debug ]--Read SqQueue OK
    42. 2023-9-12--[ Debug ]--Enter SqQueue OK
    43. 2023-9-12--[ Debug ]--Push Data To Bucket OK.
    44. 2023-9-12--[ Debug ]--Read SqQueue OK
    45. 2023-9-12--[ Debug ]--Enter SqQueue OK
    46. 2023-9-12--[ Debug ]--Push Data To Bucket OK.
    47. 2023-9-12--[ Debug ]--Read SqQueue OK
    48. 2023-9-12--[ Debug ]--Enter SqQueue OK
    49. 2023-9-12--[ Debug ]--Push Data To Bucket OK.
    50. 2023-9-12--[ Debug ]--Read SqQueue OK
    51. 2023-9-12--[ Debug ]--Enter SqQueue OK
    52. 2023-9-12--[ Debug ]--Push Data To Bucket OK.
    53. 2023-9-12--[ Debug ]--Read SqQueue OK
    54. 2023-9-12--[ Debug ]--Enter SqQueue OK
    55. 2023-9-12--[ Debug ]--Push Data To Bucket OK.
    56. 2023-9-12--[ Debug ]--Read SqQueue OK
    57. 2023-9-12--[ Debug ]--Enter SqQueue OK
    58. 2023-9-12--[ Debug ]--Push Data To Bucket OK.
    59. 2023-9-12--[ Debug ]--Read SqQueue OK
    60. 2023-9-12--[ Debug ]--Enter SqQueue OK
    61. 2023-9-12--[ Debug ]--Push Data To Bucket OK.
    62. 2023-9-12--[ Debug ]--Read SqQueue OK
    63. 2023-9-12--[ Debug ]--Enter SqQueue OK
    64. 2023-9-12--[ Debug ]--Push Data To Bucket OK.
    65. 2023-9-12--[ Debug ]--Read SqQueue OK
    66. 2023-9-12--[ Debug ]--Clear SqQueue OK
    67. 2023-9-12--[ Debug ]--Enter SqQueue OK
    68. 2023-9-12--[ Debug ]--Leave SqQueue OK
    69. 2023-9-12--[ Debug ]--Pop Data From Bucket OK.
    70. 2023-9-12--[ Debug ]--Enter SqQueue OK
    71. 2023-9-12--[ Debug ]--SqQueue is Empty, Data cannot be left
    72. 2023-9-12--[ Debug ]--Leave SqQueue OK
    73. 2023-9-12--[ Debug ]--Pop Data From Bucket OK.
    74. 2023-9-12--[ Debug ]--Enter SqQueue OK
    75. 2023-9-12--[ Debug ]--SqQueue is Empty, Data cannot be left
    76. 2023-9-12--[ Debug ]--Leave SqQueue OK
    77. 2023-9-12--[ Debug ]--Pop Data From Bucket OK.
    78. 2023-9-12--[ Debug ]--Enter SqQueue OK
    79. 2023-9-12--[ Debug ]--SqQueue is Empty, Data cannot be left
    80. 2023-9-12--[ Debug ]--Leave SqQueue OK
    81. 2023-9-12--[ Debug ]--Pop Data From Bucket OK.
    82. 2023-9-12--[ Debug ]--Enter SqQueue OK
    83. 2023-9-12--[ Debug ]--SqQueue is Empty, Data cannot be left
    84. 2023-9-12--[ Debug ]--Leave SqQueue OK
    85. 2023-9-12--[ Debug ]--Pop Data From Bucket OK.
    86. 2023-9-12--[ Debug ]--Enter SqQueue OK
    87. 2023-9-12--[ Debug ]--SqQueue is Empty, Data cannot be left
    88. 2023-9-12--[ Debug ]--Leave SqQueue OK
    89. 2023-9-12--[ Debug ]--Pop Data From Bucket OK.
    90. 2023-9-12--[ Debug ]--Enter SqQueue OK
    91. 2023-9-12--[ Debug ]--SqQueue is Empty, Data cannot be left
    92. 2023-9-12--[ Debug ]--Leave SqQueue OK
    93. 2023-9-12--[ Debug ]--Pop Data From Bucket OK.
    94. 2023-9-12--[ Debug ]--Enter SqQueue OK
    95. 2023-9-12--[ Debug ]--SqQueue is Empty, Data cannot be left
    96. 2023-9-12--[ Debug ]--Leave SqQueue OK
    97. 2023-9-12--[ Debug ]--Pop Data From Bucket OK.
    98. 2023-9-12--[ Debug ]--Enter SqQueue OK
    99. 2023-9-12--[ Debug ]--SqQueue is Empty, Data cannot be left
    100. 2023-9-12--[ Debug ]--Leave SqQueue OK
    101. 2023-9-12--[ Debug ]--Pop Data From Bucket OK.
    102. 2023-9-12--[ Debug ]--Enter SqQueue OK
    103. 2023-9-12--[ Debug ]--SqQueue is Empty, Data cannot be left
    104. 2023-9-12--[ Debug ]--Leave SqQueue OK
    105. 2023-9-12--[ Debug ]--Pop Data From Bucket OK.
    106. 2023-9-12--[ Debug ]--Enter SqQueue OK
    107. 2023-9-12--[ Debug ]--Clear SqQueue OK
    108. 2023-9-12--[ Debug ]--Clear SqQueue OK
    109. 2023-9-12--[ Debug ]--Clear SqQueue OK
    110. 2023-9-12--[ Debug ]--Clear SqQueue OK
    111. 2023-9-12--[ Debug ]--Clear SqQueue OK
    112. 2023-9-12--[ Debug ]--Clear SqQueue OK
    113. 2023-9-12--[ Debug ]--Clear SqQueue OK
    114. 2023-9-12--[ Debug ]--Clear SqQueue OK
    115. 2023-9-12--[ Debug ]--Clear SqQueue OK
    116. 2023-9-12--[ Debug ]--Clear SqQueue OK
    117. 2023-9-12--[ Debug ]--Clear Bucket OK.
    118. 2023-9-12--[ Debug ]--Destroy SqQueue OK
    119. 2023-9-12--[ Debug ]--Destroy SqQueue OK
    120. 2023-9-12--[ Debug ]--Destroy SqQueue OK
    121. 2023-9-12--[ Debug ]--Destroy SqQueue OK
    122. 2023-9-12--[ Debug ]--Destroy SqQueue OK
    123. 2023-9-12--[ Debug ]--Destroy SqQueue OK
    124. 2023-9-12--[ Debug ]--Destroy SqQueue OK
    125. 2023-9-12--[ Debug ]--Destroy SqQueue OK
    126. 2023-9-12--[ Debug ]--Destroy SqQueue OK
    127. 2023-9-12--[ Debug ]--Destroy SqQueue OK
    128. 2023-9-12--[ Debug ]--Destroy Bucket OK.
    129. 2023-9-12--[ Debug ]--Destroy SqQueue OK
    130. 2023-9-12--[ Debug ]--Bucket Sort Sentry Queue OK.
    131. 2023-9-12--[ Info ]--Sort Function Elapsed Time : 0 s
    132. 2023-9-12--[ Info ]--SqQueue Data :
    133. Data : [ 0 ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ]
    134. FrontIndex : 0
    135. RearIndex : 0
    136. SqQueueLen : 11
    137. SqQueueMaxLen : 11
    138. Flag : INT_TYPE_FLAG
    139. 2023-9-12--[ Debug ]--Destroy SqQueue OK
    140. real 0m0.002s
    141. user 0m0.002s
    142. sys 0m0.000s

  • 相关阅读:
    零拷贝原理与实现
    HTML期末学生大作业-班级校园我的校园网页设计与实现html+css+javascript
    HTML小结
    torch.cuda.OutOfMemoryError: CUDA out of memory.
    docker搭建Elasticsearch、Kibana、Logstash 同步mysql数据到ES
    李宏毅2023机器学习作业HW05解析和代码分享
    ADC噪声全面分析 -03- 利用噪声分析进行实际设计
    maven基础
    Python pip 替换国内镜像源
    绘制函数堆栈
  • 原文地址:https://blog.csdn.net/qq_45111959/article/details/132825783