经典排序算法总结

0.总述

0.1 写在前面

排序算法在数据结构与算法中算是比较基础且常用的算法之一。本篇文章主要针对十大经典排序算法进行总结,包括算法描述、动画演示、算法分析以及Python代码展示。本文中算法分析主要以分析时间复杂度为主,如不特殊说明,所有举例均按从小到大进行排序。希望读者看完本篇文章以后,对各种排序算法有初步的了解。

0.2 算法总结

其中:
n为数据规模大小,一般指待排序数组中数的个数;
k为桶的个数;
in-place为原地排序,不占用或只占用常数大小的额外存储空间;
out-place指占用额外的存储空间(非常数大小,和数据规模n有关)。

1.冒泡排序(Bubble Sort)

1.1 算法描述

冒泡排序是一种比较简单的排序算法,通过重复的遍历整个数组,如果碰到两个数顺序错误,就把他们交换位置。每次遍历数组,都会将一部分数放在正确的位置上。直到遍历数组时,没有交换发生。此时,所有数都处于正确的位置。在排序过程中,较大的数会一步一步的向数组后方移动,就好比较大的数慢慢浮出水面,因此称为冒泡排序。

1.2 动画演示

1.3 算法分析

其实在每次遍历时,我们不需要遍历整个数组(第一次遍历除外)。在经过第一次遍历以后,整个数组中最大的数一定会被放在数组的末端,因此最后一个数已经放在了正确的位置,我们只需要对前N-1个数进行排序即可。同理,第二次遍历结束后,后两个数处于正确的位置,下一次遍历前N-2个数。因此,在最坏的情况下,我们共需要((N-1)+(N-2)+…+2+1)=(N2-N)/2次比较,即时间复杂度为O(N2)。但是我们发现,如果在某一次遍历过程中,没有发生两个数交换的情况,即表示所有的数都处于正确的位置,此时我们即可以停止算法,不需要再做后续的无用功。考虑最佳情况,即整个数组本身已经是按顺序排列。当我们第一次遍历整个数组时,发现没有发生交换。此时时间复杂度为O(N)。冒泡排序有一个优点,在排序过程中所有交换均发生在原数组内部,不需要额外消耗空间,故为原地排序。

最佳情况:T(N) = O(N)
最差情况:T(N) = O(N2)
平均情况:T(N) = O(N2)

1.4 Python代码

def bubbleSort(array):
    for i in range(len(array)-1,0,-1):
        exchange=False  #记录是否有交换发生
        for j in range(i):
            if array[j]>array[j+1]:
                temp=array[j]
                array[j]=array[j+1]
                array[j+1]=temp
                exchange=True
        #如果没有交换发生,则退出循环
        if exchange==False:
            break
    return array

2.选择排序(Selection Sort)

2.1 算法描述

选择排序应该是人们首先想到的排序算法之一。其思想很简单直观,每次遍历数组,找到未排序数组中的最大值,将它放到未排序数组的最后,然后再进行下一次遍历。

2.2 动画演示
(动画演示效果为每次找到未排序数组的最小值,将其放到未排序数组的首位。)

2.3 算法分析

选择排序和冒泡排序类似,未排序的数组长度会越来越少(每次减一)。因此最坏情况时间复杂度依然为O(N2)。但是和冒泡排序不同,选择排序不会中途退出,无论原数组是否已经是有序的。假设在最佳情况下,原数组本身已经是有序的,选择排序依然需要比较整个数组,找出最大值,放到数组最后(尽管这个数本身就在数组最后)。因此选择排序在最佳情况下时间复杂度依然为O(N2)。选择排序可以说是最表现稳定的排序算法之一。因为选择排序的所有交换均发生在数组内部,因此选择排序也是一种原地排序。

最佳情况:T(N) = O(N2)
最差情况:T(N) = O(N2)
平均情况:T(N) = O(N2)

2.4 Python代码

def selectionSort(array):
    for i in range(len(array)-1,-1,-1):
        max_index=0 #记录最大值索引
        for j in range(i+1):
            if array[j]>array[max_index]:
                max_index=j
        temp=array[max_index]
        array[max_index]=array[i]
        array[i]=temp
    return array

3.插入排序(Insertion Sort)

3.1 算法描述

插入排序也是一种比较简单直观的排序方法。假设现在已经有一个有序数组,再额外给一个数,要使新数组仍然为有序数组,只需要将新添加的数插入到原有序数组中正确的位置即可,因此称为插入排序。对于长度为N的数组,只需要进行N-1次这样的操作即可(只有一个数的话本身就是有序的)。具体操作如下:
1)从第一个元素开始,该元素可以认为已经被排序
2)取出下一个元素,在已经排序的元素序列中从后向前扫描
3)如果该元素(已排序)大于新元素,将该元素移到下一位置
4)重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
5)将新元素插入到该位置后
6)重复步骤2~5

3.2 动画演示

3.3 算法分析

插入排序的最坏情况时间复杂度依然为O(N2)。设想一个逆序数组(如果排序要求为从小到大,那么假设有一个从大到小排列的数组),每次插入新数时都要将这个数遍历整个数组进行前移。在最佳情况下,原数组本身就是有序的,每次插入新数时,只需要比较一次就会发现新数已经在正确的位置,因此时间复杂度为O(N)。插入排序也是一种原地排序,所有的交换均发生在数组内部,不需要占用额外的空间。

最佳情况:T(N) = O(N)
最差情况:T(N) = O(N2)
平均情况:T(N) = O(N2)

3.4 Python代码

def insertionSort(array):
    for i in range(len(array)):
        for j in range(i,0,-1):
            if array[j]<array[j-1]:
                temp=array[j]
                array[j]=array[j-1]
                array[j-1]=temp
                continue
            break #如果新加入的数已经处于正确的位置,则退出循环
    return array

4.希尔排序(Shell Sort)

4.1 算法描述

希尔排序是插入排序算法的改进版。插入排序算法对于已经是有序的数组或者数组中大部分数有序的数组排序时间较快,几乎为线性时间。因此,希尔算法将整个数组分为若干组,首先对每组中的元素进行排序,使整个数组达到基本有序的状态,最后再对整个数组进行排序,从而提高效率。具体操作如下:
1)首先选定一个增量序列{t1,t2,…,tk,其中ti>tj (i<j),tk=1}
2)根据增量讲整个数组每隔ti个数分为一组,总共分成m组,使用插入排序对这m组分别排序
3)根据增量序列选取下一个增量,重复步骤2,直到增量为1(即tk),此时即为普通的插入排序

4.2 过程演示

4.3 算法分析

希尔排序的时间复杂度与增量序列的选取有关,增量序列的选取和证明是个数学难题。通常选取{n/2,(n/2)/2…1}(n为数组长度),这个序列叫作希尔增量。希尔增量是最常用的,但不是最优的。同时还有Hibbard增量:{1, 3, …, 2^k-1}等。

希尔增量最坏情况:T(N)=O(N2)
Hibbard增量最坏情况:T(N)=O(N3/2)

4.4 Python代码

def shellSort(array):
    gap=len(array)//2
    while True:
        for i in range(gap):
            for j in range(i,len(array),gap):
                for k in range(j,0,-gap):
                    if array[k]<array[k-gap]:
                        temp=array[k]
                        array[k]=array[k-gap]
                        array[k-gap]=temp
                        continue
                    break
        if gap<=1:
            break
        gap=gap//2
    return array

5.归并排序(Merge Sort)

5.1 算法描述

归并排序是使用分治法(Divide and Conquer)的一个典型应用。假设有两个有序数组,如何将他们合并为一个有序数组呢?很简单,只需要比较两个数组的第一个元素,选取一个小的拿出来放到新数组里,然后把这个数从原来的数组删除,继续比较两个数组的第一个元素,重复上述过程。分治法的基本思想就是,将一个大问题分解为若干个思路相同的小问题。即,如果要对一个数组排序,我们可以先将原数组分成两个长度相同(或者长度差1)的数组,对这两个数组进行排序,如果这两个数组有序,便可以使用刚才的方法合并为一个大的有序数组。这两个数组的排序方法仍然可以使用归并排序,即分解为长度更小的数组,直到数组的长度为1。

5.2 动画演示

5.3 算法分析

归并排序和选择排序相同,排序的性能不受输入数据的影响,时间复杂度始终为O(N*log(N)),但是需要额外O(N)的存储空间。考虑两个N/2长度的有序数据要合并为一个长度为N的有序数组,总共需要比较N次。一个长度为N/2的数组需要两个长度为N/4的有序数组比较N/2次得到,即四个长度为N/4的有序数组,先比较N次得到两个长度为N/2的有序数组,再比较N次得到长度为N的有序数组。综上,有序数组长度每减一半,都需要增加N次比较操作。长度为N的数组需要执行log(N)次操作得到长度为1的(有序)数组,故总时间复杂度为O(N*log(N))。

最佳情况:T(N) = O(N*log(N))
最差情况:T(N) = O(N*log(N))
平均情况:T(N) = O(N*log(N))

5.4 Python代码

def mergeSort(array):
    length=len(array)
    if len(array)<=1:
        return array
    array_1=array[:length//2]
    array_2=array[length//2:]
    return merge(mergeSort(array_1),mergeSort(array_2))
    
def merge(array1,array2):
    l1=len(array1)
    l2=len(array2)
    i=0
    j=0
    new_array=[]
    while True:
        if array1[i]<array2[j]:
            new_array.append(array1[i])
            i+=1
            if i==l1:
                new_array.extend(array2[j:])
                break
        else:
            new_array.append(array2[j])
            j+=1
            if j==l2:
                new_array.extend(array1[i:])
                break
    return new_array

6.快速排序(Quick Sort)

6.1 算法描述

快速排序的基本思想是:选取数组中的一个数作为基准(pivot),将数组中比基准小的数放在左边,比基准大的数放在右边,基准在中间。经过这样一次操作,基准左侧的数永远比基准右侧的数小。此时,使用递归的方法对基准左侧和右侧的子数组再使用快速排序方法排序,最终得到有序数组。

6.2 动画演示

6.3 算法分析

最佳情况下,基准选的好,每一次根据基准排序时,都正好有一半的数比基准小,一半的数比基准大,如此操作,log(N)次之后,整个数组便为有序,此时时间复杂度为O(N*log(N)) 。但是在最差情况下,基准选取的不好,例如基准每次都选取最小值,就像选择排序一样,这时时间复杂度便回到了O(N2)。通常情况下,基准会选取未排序数组中的第一个数。

最佳情况:T(N) = O(N*log(N))
最差情况:T(N) = O(N2)
平均情况:T(N) = O(N*log(N))

6.4 Python代码

注:快速排序本身是一种原地排序算法,但是为了方便理解,代码中使用了额外的空间存储left(比基准小的数)、mid(和基准一样大的数)、right(比基准大的数)。

def quickSort(array):
    if len(array)<=1:
        return array
    pivot=array[0]
    left=[]
    right=[]
    mid=[]
    for value in array:
        if value<pivot:
            left.append(value)
        elif value==pivot:
            mid.append(value)
        elif value>pivot:
            right.append(value)
    return quickSort(left)+mid+quickSort(right)

7.堆排序(Heap Sort)

7.1 算法描述

堆排序是一种利用这种数据结构进行的排序方法。堆是一种完全二叉树,并且每个节点的值都大于或等于其子节点的值(这里考虑大顶堆)。如果我们每次都拿出大顶堆的堆顶放在数组中未排序部分的最后,便可以将原数组按从小到大的顺序排列起来。因此,堆排序具体操作步骤如下:
1)将未排序原数组按照大顶推的规则建立大顶堆
2)取出大顶堆堆顶,将其放在原数组中未排序部分的最后
3)将堆尾元素放至堆顶,按照大顶堆规则重新调整大顶堆
4)重复3和4直到所有元素被取出
关于堆的构造等详细介绍请看这里(正在写啦)

7.2 动画演示

7.3 算法分析

在堆排序过程中,构建大顶堆的时间复杂度为O(N),更改堆元素后重建大顶堆的时间复杂度为O(N*log(N))。因此,堆排序的总时间复杂度为O(N*log(N))。详细关于堆的时间复杂度请看这里(正在写啦)

最佳情况:T(N) = O(N*log(N))
最差情况:T(N) = O(N*log(N))
平均情况:T(N) = O(N*log(N))

7.4 Python代码

def buildMaxHeap(array):
    for i in range(len(array)//2,-1,-1):
        heapify(array,i)
    
def heapify(array,i):
    left=2*i+1
    right=2*i+2
    largest=i
    if left<length and array[left]>array[largest]:
        largest=left
    if right<length and array[right]>array[largest]:
        largest=right
    
    if largest!=i:
        swap(array,i,largest)
        heapify(array,largest)
        
def swap(array,i,j):
    array[i],array[j]=array[j],array[i]
    
def heapSort(array):
    global length
    length=len(array)
    buildMaxHeap(array)
    for i in range(length-1,0,-1):
        swap(array,0,i)
        length-=1
        heapify(array,0)
    return array

8.计数排序(Counting Sort)

8.1 算法描述

计数排序也是一种比较简单直观的排序方法,计数排序要求输入数据必须是有明确范围的整数。假设一个要排序的数组范围是0~9,我们可以创建一个额外的数组,记录0在数组中出现了多少次,1出现了多少次等等。例如最后记录显示原数组中有3个0,2个1等等,我们可以把3个0放在数组的开头,然后把2个1紧接着0放,以此类推。

8.2 动画演示

8.3 算法分析

计数算法的优点在于,访问计数数组只需要O(1)的时间复杂度。假设未排序数组中有N个数,其范围为K(待排序数组中最大值减最小值加一),我们创建一个长度为K的数组记录每个数出现的次数,遍历整个未排序数组,统计每个数出现的次数,共N次。再遍历整个计数数组,按从小到大的顺序把每个数还原到原数组当中,共K次。因此,计数排序的时间复杂度为O(N+K)。计数排序对于数据范围很大的数组,需要很大的额外空间和时间,因此计数排序经常用于数据范围较小的数组。

最佳情况:T(N) = O(N+K)
最差情况:T(N) = O(N+K)
平均情况:T(N) = O(N+K)

8.4 Python代码

def countingSort(array):
    max_=max(array)
    min_=min(array)
    bias=min(array)
    counting=[0 for i in range(max_-min_+1)]
    for value in array:
        counting[value-bias]+=1
    array=[]
    for i in range(len(counting)):
        array.extend([i+bias]*counting[i])
    return array

9.桶排序(Bucket Sort)

9.1 算法描述

桶排序实际上是计数排序的改进版,同样需要知道未排序数组的数据范围。我们规定一个桶只能存放一定范围的数据,然后使用多个桶将原数组中的数分类,将每个桶中的数据排序以后,再按桶的顺序将桶中的数送回原数组。假设现在要排序的范围为0~99,并且规定0~9的数放在1号桶中,10~19的数放在2号桶中,以此类推。然后我们分别将1号桶,2号桶。。。中的数据排序,最后按桶的顺序将1号桶的数据送回原数组,2号桶的数据紧跟着1号桶,等等。

计数排序也是一种桶排序,只是每个桶中数据的范围为1。相比于计数排序,桶排序节省了额外的空间和时间。假设原数组在10~49中都没有数据,那么根据计数排序,我们需要40个单位的空间存储10~49的个数(尽管个数都为0),同时在回放时,需要遍历这40个单位的空间(虽然什么都没有放回)。但是根据桶排序,我们只需要4个桶来存储这些数据,如果10~49没有数据,那么这4个桶为空,仅仅只占用了4个单位空间,在回放遍历时,我们只需要看到这4个桶为空,便知道10~49都没有数据,即节省了时间也节省了空间。

9.2 动画演示

9.3 算法分析

桶排序的时间复杂度取决于在桶中的元素排序时所使用的算法复杂度。

9.4 Python代码

def bucketSort(array):
    max_=max(array)
    min_=min(array)
    bucket = [[] for i in range(max_ // 10 - min_ // 10 + 1)] 
    for i in array:
        index = i // 10 - min_ // 10
        bucket[index].append(i)
    array.clear()
    for i in bucket:
        array.extend(countingSort(i))
    return array

10.基数排序(Radix Sort)

10.1 算法描述

基数排序仍然运用到了桶的概念,根据每一位的不同将未排序数组的数分配至不同的桶。首先我们对最低位排序,将末位为0的数都存放在0号桶中,末位为1的数存放在1号桶中,以此类推。然后将桶中的数送回原数组进行第二次排序。经过第一次排序以后,整个数组针对最低位来说已经是有序的了。第二轮排序将十位为0的数放在0号桶中,十位为1的数放在1号桶中。。。此时每个桶中的数针对末两位来说已经是有序的,我们再按桶的顺序将桶中的数送回原数组中。反复执行该操作,直到达到最大数的最高位,此时,所有数均是有序排列的。

10.2 动画演示

10.3 算法分析

基数排序的时间复杂度始终为O(N*K),其中N为未排序数组的个数,K为最大数的最高位位数。(这里最大数指偏移后的最大数)。若原数组中有负数存在,我们可以先将所有数减去最小数,迫使最小数为0,所有数均不是负数(即偏移操作),此时可以按照前面讲的方法进行排序,最后将排序结果中的所有数加上最小数,还原至原数组即可。可以想象我们每次根据某一位将数组中的数放入桶时,都要遍历整个数组,即N次。同时,最大数总共有K位,我们就需要K次遍历,因此总次数为N*K。

最佳情况:T(N) = O(N*K)
最差情况:T(N) = O(N*K)
平均情况:T(N) = O(N*K)

10.4 Python代码

def radixSort(array):
    bias=min(array)
    array=[i-bias for i in array]
    max_=max(array)
    a=10
    b=1
    while True:
        bucket=[[] for i in range(10)]
        for value in array:
            index=value%a//b
            bucket[index].append(value)
        array.clear()
        for value in bucket:
            array.extend(value)
        if a>max_:
            break
        else:
            a*=10
            b*=10
    return [i+bias for i in array]

写在后面

本篇文章中的所有代码均为博主自己所写,由于博主知识有限,代码可能不是最优但亲测可用。如果读者发现文章中出现错误,或者代码分析讲解不清,欢迎在文末提问回复。
另:本文的算法过程动画均来源于网络,感谢原作者的付出。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值