热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python实现十大经典排序算法[冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序]动画演示

目录多种排序的平均时间复杂度如下:1.冒泡排序算法步骤2.插入排序算法步骤:3.选择排序算法步骤:4.希尔排序算法步骤

目录

多种排序的平均时间复杂度如下:

1.冒泡排序

算法步骤

2.插入排序

算法步骤:

3.选择排序

算法步骤:

4.希尔排序

算法步骤

5.归并排序

算法步骤

6.快速排序

算法步骤:

7.堆排序

算法步骤

8.计数排序

算法步骤:

9.桶排序

10.基数排序

算法步骤:

关于对---基数排序 vs 计数排序 vs 桶排序的比较:


排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序, 而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。 常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。

  • 平方阶 (O(n2)) 排序 各类简单排序:直接插入、直接选择和冒泡排序。

  • 线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序。

  • O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。 希尔排序。

  • 线性阶 (O(n)) 排序 基数排序,此外还有桶、箱排序。


多种排序的平均时间复杂度如下:


排序算法平均时间复杂度
冒泡排序O(n2)
选择排序O(n2)
插入排序O(n2)
希尔排序O(n1.5)
快速排序O(N*logN)
归并排序O(N*logN)
堆排序O(N*logN)
基数排序O(d(n+r))

1.冒泡排序

时间复杂度为O(n2)

算法步骤


  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。

  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

  • 针对所有的元素重复以上的步骤,除了最后一个。

  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较!

演示动画:

img

python代码实现:

arr0 = [3,44,38,5,47,15,36,26,27,44,46,4,19,50,48]

#冒泡排序
def bubbleSort(arr):for i in range(1,len(arr)):for j in range(0,len(arr)-i):if arr[j]>arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]return arr

arr1 = bubbleSort(arr0)
print("冒泡排序 arr1 =",arr1)


2.插入排序


算法步骤:


  • 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

  • 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。

  • 如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。

算法演示动画:

img

Python实现代码:

arr0 = [3,44,38,5,47,15,36,26,27,44,46,4,19,50,48]

def insertionSort(arr):for i in range(len(arr)):preIndex = i-1current = arr[i]while preIndex >= 0 and arr[preIndex] > current:arr[preIndex+1] = arr[preIndex]preIndex-=1arr[preIndex+1] = currentreturn arr
arr2 = insertionSort(arr0)
print("插入排序 arr2 =",arr2)

3.选择排序

时间复杂度为O(n2)

算法步骤:


  • 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

  • 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

  • 重复第二步,直到所有元素均排序完毕。

算法动画实现:

img

python代码实现:

arr0 = [3,44,38,5,47,15,36,26,27,44,46,4,19,50,48]

def selectionSort(arr):for i in range(len(arr) - 1):# 记录最小数的索引minIndex = ifor j in range(i + 1, len(arr)):if arr[j]

4.希尔排序

平均时间复杂度:O(n1.5)

希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  • 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;

  • 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;

希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。

算法步骤


  • 选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;

  • 按增量序列个数 k,对序列进行 k 趟排序;

  • 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

算法动画实现:

img

代码实现:

arr0 = [3,44,38,5,47,15,36,26,27,44,46,4,19,50,48]

def shellSort(arr):import mathgap=1while(gap 0:for i in range(gap,len(arr)):temp = arr[i]j = i-gapwhile j >=0 and arr[j] > temp:arr[j+gap]=arr[j]j-=gaparr[j+gap] = tempgap = math.floor(gap/3)  ##向下取整return arr
arr3 = shellSort(arr0)
print("希尔排序 arr3 =",arr3)


5.归并排序

平均时间复杂度:O(N*logN)

归并排序是一种非常典型的 “分而治之+迭代” 思想的排序方法!

作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:

  • 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法);

  • 自下而上的迭代;


算法步骤


  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;

  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置;

  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;

  4. 重复步骤 3 直到某一指针达到序列尾;

  5. 将另一序列剩下的所有元素直接复制到合并序列尾。

算法动画演示:

算法演示

 

img

python实现代码:

arr0 = [3,44,38,5,47,15,36,26,27,44,46,4,19,50,48]

def mergeSort(arr):  ###对每一份单独排序&#xff01;import mathif(len(arr)<2):return arrmiddle &#61; math.floor(len(arr)/2)  ##向下取整left, right &#61; arr[0:middle], arr[middle:]return merge(mergeSort(left), mergeSort(right))  ##利用典型的递归思想&#xff01;

def merge(left,right):  ###将两份整合起来&#xff01;result &#61; []while left and right:if left[0] <&#61; right[0]:result.append(left.pop(0));else:result.append(right.pop(0));while left:result.append(left.pop(0));while right:result.append(right.pop(0));return result
arr4 &#61; mergeSort(arr0)
print("归并排序 arr4 &#61;",arr4)

6.快速排序

平均时间复杂度&#xff1a;O(N*logN)

快速排序在平均状况下&#xff0c;排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较&#xff0c;但这种状况并不常见。事实上&#xff0c;快速排序通常明显比其他 Ο(nlogn) 算法更快&#xff0c;因为它的内部循环&#xff08;inner loop&#xff09;可以在大部分的架构上很有效率地被实现出来。

快速排序使用分治法&#xff08;Divide and conquer&#xff09;策略来把一个串行&#xff08;list&#xff09;分为两个子串行&#xff08;sub-lists&#xff09;。

快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看&#xff0c;快速排序应该算是在冒泡排序基础上的递归分治法。

快速排序的名字起的是简单粗暴&#xff0c;因为一听到这个名字你就知道它存在的意义&#xff0c;就是快&#xff0c;而且效率高&#xff01;它是处理大数据最快的排序算法之一了。虽然最坏的条件下的时间复杂度达到了 O(n²)&#xff0c;但是在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好&#xff01;

算法步骤&#xff1a;


  1. 从数列中挑出一个元素&#xff0c;称为 "基准"&#xff08;pivot&#xff09;;

  2. 重新排序数列&#xff0c;所有元素比基准值小的摆放在基准前面&#xff0c;所有元素比基准值大的摆在基准的后面&#xff08;相同的数可以到任一边&#xff09;。在这个分区退出之后&#xff0c;该基准就处于数列的中间位置。这个称为分区&#xff08;partition&#xff09;操作&#xff1b;

  3. 递归地&#xff08;recursive&#xff09;把小于基准值元素的子数列和大于基准值元素的子数列排序&#xff1b;

算法动画演示&#xff1a;

算法演示

img

python代码如下&#xff1a;

arr0 &#61; [3,44,38,5,47,15,36,26,27,44,46,4,19,50,48]

def quickSort(arr, left&#61;None, right&#61;None):left &#61; 0 if not isinstance(left,(int, float)) else leftright &#61; len(arr)-1 if not isinstance(right,(int, float)) else rightif left
def partition(arr, left, right):pivot &#61; leftindex &#61; pivot&#43;1i &#61; indexwhile  i <&#61; right:if arr[i]
def swap(arr, i, j):arr[i], arr[j] &#61; arr[j], arr[i]
arr5 &#61; quickSort(arr0)
print("快速排序 arr5 &#61;",arr5)

7.堆排序

平均时间复杂度&#xff1a;O(N*logN)

堆排序&#xff08;Heapsort&#xff09;是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构&#xff0c;并同时满足堆积的性质&#xff1a;即子结点的键值或索引总是小于&#xff08;或者大于&#xff09;它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。

分为两种方法&#xff1a;

  1. 大顶堆&#xff1a;每个节点的值都大于或等于其子节点的值&#xff0c;在堆排序算法中用于升序排列&#xff1b;

  2. 小顶堆&#xff1a;每个节点的值都小于或等于其子节点的值&#xff0c;在堆排序算法中用于降序排列&#xff1b;


算法步骤


  1. 创建一个堆 H[0……n-1]&#xff1b;

  2. 把堆首&#xff08;最大值&#xff09;和堆尾互换&#xff1b;

  3. 把堆的尺寸缩小 1&#xff0c;并调用 shift_down(0)&#xff0c;目的是把新的数组顶端数据调整到相应位置&#xff1b;

  4. 重复步骤 2&#xff0c;直到堆的尺寸为 1。

算法动画演示&#xff1a;

img

img

python代码实现&#xff1a;

arr0 &#61; [3,44,38,5,47,15,36,26,27,44,46,4,19,50,48]

def buildMaxHeap(arr):import mathfor i in range(math.floor(len(arr)/2),-1,-1):heapify(arr,i)

def heapify(arr, i):left &#61; 2*i&#43;1right &#61; 2*i&#43;2largest &#61; iif left arr[largest]:largest &#61; leftif right arr[largest]:largest &#61; right
​if largest !&#61; i:swap(arr, i, largest)heapify(arr, largest)

def swap(arr, i, j):arr[i], arr[j] &#61; arr[j], arr[i]

def heapSort(arr):global arrLenarrLen &#61; len(arr)buildMaxHeap(arr)for i in range(len(arr)-1,0,-1):swap(arr,0,i)arrLen -&#61;1heapify(arr, 0)return arr
arr6 &#61; heapSort(arr0)
print("堆 排 序 arr6 &#61;",arr6)

8.计数排序

平均时间复杂度&#xff1a;O(n&#43;k)

计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序&#xff0c;计数排序要求输入的数据必须是有确定范围的整数。( “ 输入数据必须是有确定范围是关键 ” &#xff01;&#xff01;)

计数排序的特征:

当输入的元素是 n 个 0 到 k 之间的整数时&#xff0c;它的运行时间是 Θ(n &#43; k)。计数排序不是比较排序&#xff0c;排序的速度快于任何比较排序算法。

由于用来计数的数组C的长度取决于待排序数组中数据的范围&#xff08;等于待排序数组的最大值与最小值的差加上1&#xff09;&#xff0c;这使得计数排序对于数据范围很大的数组&#xff0c;需要大量时间和内存。例如&#xff1a;计数排序是用来排序0到100之间的数字的最好的算法&#xff0c;但是它不适合按字母顺序排序人名。但是&#xff0c;计数排序可以用在基数排序中的算法来排序数据范围很大的数组。

通俗地理解&#xff0c;例如有 10 个年龄不同的人&#xff0c;统计出有 8 个人的年龄比 A 小&#xff0c;那 A 的年龄就排在第 9 位,用这个方法可以得到其他每个人的位置,也就排好了序。当然&#xff0c;年龄有重复时需要特殊处理&#xff08;保证稳定性&#xff09;&#xff0c;这就是为什么最后要反向填充目标数组&#xff0c;以及将每个数字的统计减去 1 的原因。

算法步骤&#xff1a;


  • 找出待排序的数组中最大和最小的元素

  • 统计数组中每个值为i的元素出现的次数&#xff0c;存入数组C的第i项

  • 对所有的计数累加&#xff08;从C中的第一个元素开始&#xff0c;每一项和前一项相加&#xff09;

  • 反向填充目标数组&#xff1a;将每个元素i放在新数组的第C(i)项&#xff0c;每放一个元素就将C(i)减去1

算法动画实现&#xff1a;

img

python代码实现&#xff1a;

def countingSort(arr, maxValue):bucketLen &#61; maxValue&#43;1bucket &#61; [0]*bucketLensortedIndex &#61;0arrLen &#61; len(arr)for i in range(arrLen):if not bucket[arr[i]]:bucket[arr[i]]&#61;0bucket[arr[i]]&#43;&#61;1for j in range(bucketLen):while bucket[j]>0:arr[sortedIndex] &#61; jsortedIndex&#43;&#61;1bucket[j]-&#61;1return arr
arr7 &#61; countingSort(arr0,50)
print("计数排序 arr7 &#61;",arr7)

9.桶排序

平均时间复杂度&#xff1a;O&#xff08;n&#xff09;

桶排序是计数排序的升级版。它利用了函数的映射关系&#xff0c;高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效&#xff0c;我们需要做到这两点&#xff1a;

  1. 在额外空间充足的情况下&#xff0c;尽量增大桶的数量

  2. 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中

同时&#xff0c;对于桶中元素的排序&#xff0c;选择何种比较排序算法对于性能的影响至关重要。

① 什么时候最快&#xff1f;

当输入的数据可以均匀的分配到每一个桶中。

②什么时候最慢&#xff1f;

当输入的数据被分配到了同一个桶中。

③示意图

元素分布在桶中&#xff1a;

img

之后&#xff0c;对每个桶中的元素进行排序&#xff1a;

img

python代码实现&#xff1a;

arr0 &#61; [3,44,38,5,47,15,36,26,27,44,46,4,19,50,48]
def bucketSort(nums):# 选择一个最大的数max_num &#61; max(nums)# 创建一个元素全是0的列表, 当做桶bucket &#61; [0] * (max_num &#43; 1)# 把所有元素放入桶中, 即把对应元素个数加一for i in nums:bucket[i] &#43;&#61; 1# 存储排序好的元素sort_nums &#61; []# 取出桶中的元素for j in range(len(bucket)):if bucket[j] !&#61; 0:for y in range(bucket[j]):sort_nums.append(j)return sort_nums
a &#61; bucketSort(arro)
print(a)

Java代码实现&#xff1a;

public class BucketSort implements IArraySort {
​private static final InsertSort insertSort &#61; new InsertSort();
​&#64;Overridepublic int[] sort(int[] sourceArray) throws Exception {// 对 arr 进行拷贝&#xff0c;不改变参数内容int[] arr &#61; Arrays.copyOf(sourceArray, sourceArray.length);
​return bucketSort(arr, 5);}
​private int[] bucketSort(int[] arr, int bucketSize) throws Exception {if (arr.length &#61;&#61; 0) {return arr;}
​int minValue &#61; arr[0];int maxValue &#61; arr[0];for (int value : arr) {if (value maxValue) {maxValue &#61; value;}}
​int bucketCount &#61; (int) Math.floor((maxValue - minValue) / bucketSize) &#43; 1;int[][] buckets &#61; new int[bucketCount][0];
​// 利用映射函数将数据分配到各个桶中for (int i &#61; 0; i ​int arrIndex &#61; 0;for (int[] bucket : buckets) {if (bucket.length <&#61; 0) {continue;}// 对每个桶进行排序&#xff0c;这里使用了插入排序bucket &#61; insertSort.sort(bucket);for (int value : bucket) {arr[arrIndex&#43;&#43;] &#61; value;}}
​return arr;}
​/*** 自动扩容&#xff0c;并保存数据** &#64;param arr* &#64;param value*/private int[] arrAppend(int[] arr, int value) {arr &#61; Arrays.copyOf(arr, arr.length &#43; 1);arr[arr.length - 1] &#61; value;return arr;}

}

10.基数排序

时间复杂度为nlog (r)m (其中r为的采取的基数,m为堆数)&#xff0c;基数排序的效率有时候高于其它比较性排序。

基数排序(Radix Sort)是一种非比较型整数排序算法&#xff0c;是桶排序的扩展。

基本思想是&#xff1a;将所有待比较数值统一为同样的数位长度&#xff0c;数位较短的数前面补零。按照低位先排序&#xff0c;分别放入10个队列中&#xff0c;然后采用先进先出的原则进行收集&#xff1b;再按照高位排序&#xff0c;然后再收集&#xff1b;依次类推&#xff0c;直到最高位&#xff0c;最终得到排好序的数列。对于数值偏小的一组序列&#xff0c;其速度是非常快的&#xff0c;时间复杂度达到了线性&#xff0c;而且思想也非常的巧妙。

算法步骤&#xff1a;


  1. 取得数组中的最大数&#xff0c;并取得位数&#xff1b;

  2. 对数位较短的数前面补零&#xff1b;

  3. 分配&#xff0c;先从个位开始&#xff0c;根据位值(0-9)分别放到0~9号桶中;

  4. 收集&#xff0c;再将放置在0~9号桶中的数据按顺序放到数组中;

  5. 重复3~4过程&#xff0c;直到最高位&#xff0c;即可完成排序。

LSD基数排序动画示意图&#xff1a;

img

python代码实现&#xff1a;

from typing import List

def radix_sort(arr:List[int]):n &#61; len(str(max(arr)))  # 记录最大值的位数for k in range(n): # n轮排序# 每一轮生成10个列表bucket_list&#61;[[] for i in range(10)]#因为每一位数字都是0~9&#xff0c;故建立10个桶for i in arr:# 按第k位放入到桶中bucket_list[i//(10**k)%10].append(i)# 按当前桶的顺序重排列表arr&#61;[j for i in bucket_list for j in i]return arr

# 测试数据

if __name__ &#61;&#61; &#39;__main__&#39;:import randomrandom.seed(54)arr &#61; [random.randint(0,100) for _ in range(10)]print("原始数据&#xff1a;", arr)arr_new &#61; radix_sort(arr)print("计数排序结果为&#xff1a;", arr_new)

# 输出结果

原始数据&#xff1a; [17, 56, 71, 38, 61, 62, 48, 28, 57, 42]
计数排序结果为&#xff1a; [17, 28, 38, 42, 48, 56, 57, 61, 62, 71]

Java代码实现&#xff1a;

public class RadixSort implements IArraySort {
​&#64;Overridepublic int[] sort(int[] sourceArray) throws Exception {// 对 arr 进行拷贝&#xff0c;不改变参数内容int[] arr &#61; Arrays.copyOf(sourceArray, sourceArray.length);
​int maxDigit &#61; getMaxDigit(arr);return radixSort(arr, maxDigit);}
​/*** 获取最高位数*/private int getMaxDigit(int[] arr) {int maxValue &#61; getMaxValue(arr);return getNumLenght(maxValue);}
​private int getMaxValue(int[] arr) {int maxValue &#61; arr[0];for (int value : arr) {if (maxValue ​protected int getNumLenght(long num) {if (num &#61;&#61; 0) {return 1;}int lenght &#61; 0;for (long temp &#61; num; temp !&#61; 0; temp /&#61; 10) {lenght&#43;&#43;;}return lenght;}
​private int[] radixSort(int[] arr, int maxDigit) {int mod &#61; 10;int dev &#61; 1;
​for (int i &#61; 0; i ​for (int j &#61; 0; j ​int pos &#61; 0;for (int[] bucket : counter) {for (int value : bucket) {arr[pos&#43;&#43;] &#61; value;}}}
​return arr;}
​/*** 自动扩容&#xff0c;并保存数据** &#64;param arr* &#64;param value*/private int[] arrayAppend(int[] arr, int value) {arr &#61; Arrays.copyOf(arr, arr.length &#43; 1);arr[arr.length - 1] &#61; value;return arr;}
}

关于对---基数排序 vs 计数排序 vs 桶排序的比较&#xff1a;

这三种排序算法都利用了桶的概念&#xff0c;但对桶的使用方法上有明显差异&#xff1a;

  • 基数排序&#xff1a;根据键值的每位数字来分配桶&#xff1b;

  • 计数排序&#xff1a;每个桶只存储单一键值&#xff1b;

  • 桶排序&#xff1a;每个桶存储一定范围的数值&#xff1b;

End···



推荐阅读
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Day2列表、字典、集合操作详解
    本文详细介绍了列表、字典、集合的操作方法,包括定义列表、访问列表元素、字符串操作、字典操作、集合操作、文件操作、字符编码与转码等内容。内容详实,适合初学者参考。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
author-avatar
无情泪看红尘
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有