Go语言十大排序算法

article/2025/10/13 2:17:54

文章目录

  • Go语言十大排序算法
  • 0x01 冒泡排序
  • 0x02 选择排序
  • 0x03 插入排序
  • 0x04 希尔排序
  • 0x05 归并排序
  • 0x06 快速排序
  • 0x07 堆排序
  • 0x08 计数排序
  • 0x09 桶排序
  • 0x10 基数排序
  • 总结
    • 按时间复杂度分类:
    • 按稳定性分类
    • 按排序方式

Go语言十大排序算法

在这里插入图片描述

  • 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面;
  • 不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面;
  • 内排序:所有排序操作都在内存中完成;
  • 外排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行;
  • 时间复杂度: 一个算法执行所耗费的时间。
  • 空间复杂度: 运行完一个程序所需内存的大小。

均以升序为例

0x01 冒泡排序

冒泡排序是最简单直观的排序方式,通过比较前后两个元素的大小,然后交换位置来实现排序。

每次比较相邻两个数的大小,如果前面的数大于后面的数,则交换两个数的位置(否则不变),向后移动。

// 冒泡排序
func BubbleSort(arr []int){n := len(arr)for i:=0; i<n-1; i++{for j:=i+1; j<n; j++{if arr[i] > arr[j]{arr[i], arr[j] = arr[j], arr[i]}}}fmt.Println(arr)
}

改进冒泡排序:

冒泡排序第1次遍历后会将最大值放到最右边,这个最大值也是全局最大值。同理,当前轮的最大值也都会放在最后,每轮结束后,最大值、次大值。。。都会固定,但是普通版冒泡排序每次都会比较全部元素。可以记录每轮比较后最后一个位置,也可以逆序遍历。

// 改进的冒泡排序
func BubbleSort2(arr []int){n := len(arr)for i:=n-1; i>0; i--{    // 逆序遍历for j:=0; j<i; j++{if arr[j] > arr[j+1]{arr[j], arr[j+1] = arr[j+1], arr[j]}}}fmt.Println(arr)
}

0x02 选择排序

选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。

算法步骤:

  1. 初始序列arr,无序。分成有序区和无序区,有序区初始为0,不断变大;无序区初始为len(arr),不断变小。
  2. 遍历无序找到最小值,与无序区最左边交换。有序区长度+1。
  3. 重复第二步。
// 选择排序
func SelectionSort(arr []int){n := len(arr)for i:=0; i<n-1; i++{minNumIndex := i    // 无序区第一个for j:=i+1; j<n; j++{if arr[j] < arr[minNumIndex]{minNumIndex = j}}arr[i], arr[minNumIndex] = arr[minNumIndex], arr[i]}fmt.Println(arr)
}

0x03 插入排序

插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。

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

从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

// 插入排序
func InsertionSort(arr []int){for i := range arr{preIndex := i-1current := arr[i]for preIndex >= 0 && arr[preIndex] > current{  // 移动arr[preIndex+1] = arr[preIndex]preIndex--}arr[preIndex+1] = current}fmt.Println(arr)
}
// 插入排序1
func InsertionSort1(arr []int){n := len(arr)for i:=1; i<n; i++{tmp := arr[i]j:=i-1for ; j>=0 && tmp<arr[j];j--{arr[j+1] = arr[j]}arr[j+1] = tmp}fmt.Println(arr)
}

改进插入排序: 查找插入位置时使用二分查找的方式

// 改进版插入排序
func InsertionSort2(arr []int){n := len(arr)for i:=1; i<n; i++{   // 无序区tmp := arr[i]left, right := 0, i-1for left<=right{mid := (left+right)/2if arr[mid] > tmp{right = mid-1}else{left = mid+1}}j:=i-1for ; j>=left; j--{   // 有序区arr[j+1] = arr[j]}arr[left] = tmp}fmt.Println(arr)
}

0x04 希尔排序

希尔排序又称递减增量排序、缩小增量排序,是简单插入排序的改进版,但是是非稳定算法。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  • 插入算法在对几乎已经排好序的数据操作时,效率高,即可达线性排序效率
  • 但插入排序一般来说是低效的,因为每次只能将数据移动一位

希尔排序的基本思想是:先将整个待排序列分割成若干个子序列,对若个子序列分别进行插入排序,待整个待排序列基本有序时,对整体进行插入排序。

算法步骤:

  1. 选择一个增量序列t1,t2,…,tk,其中ti>ti+1,tk=1;
  2. 按增量序列个数k,对序列进行k 趟排序;
  3. 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

其实是两个两个换位置,将整个序列变成基本排好序的
在这里插入图片描述

// 希尔排序
func ShellSort(arr []int){n := len(arr)for gap:=n/2; gap>=1; gap=gap/2{   // 缩小增量序列,希尔建议每次缩小一半for i:=gap; i<n; i++{		// 子序列tmp := arr[i]j:=i-gapfor ; j>=0 && tmp<arr[j]; j=j-gap{arr[j+gap] = arr[j]}arr[j+gap] = tmp}}fmt.Println(arr)
}

0x05 归并排序

归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

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

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

递归版:

// 归并排序--递归版
func MergeSort(arr []int) []int{n := len(arr)if n < 2{return arr}mid := n/2left := arr[:mid]right := arr[mid:]return merge(MergeSort(left), MergeSort(right))}
func merge(left, right []int) []int{res := []int{}for len(left)!=0 && len(right)!=0{if left[0] <= right[0]{res = append(res, left[0])left = left[1:]		// 将头一个直接切出去}else {res = append(res, right[0])right = right[1:]}}if len(left) == 0{		// left结束,right剩下的直接拖下来res = append(res, right...)}if len(right) == 0{		// right结束,left剩下的直接拖下来res = append(res, left...)}return res
}

迭代版:

// 归并排序--迭代版
func MergeSort2(arr []int) []int{n := len(arr)min := func(a, b int) int{if a < b{return a}return b}for step:=1; step<=n; step<<=1{		// 外层控制步长offset := 2*stepfor i:=0; i<n; i+=offset{		// 内层控制分组h2 := min(i+step, n-1)		// 第二段头部,防止超过数组长度tail2 := min(i+offset-1, n-1)	// 第二段尾部merge2(arr, i, h2, tail2)}}return arr
}func merge2(arr []int, h1 int, h2 int, tail2 int){start := h1tail1 := h2-1	// 第一段尾部length := tail2-h1+1	// 两段长度和tmp := []int{}for h1 <= tail1 || h2 <= tail2{   // 其中一段未结束if h1 > tail1 {		// 第一段结束,处理第二段tmp = append(tmp, arr[h2])h2++}else if h2 > tail2{	// 第二段结束,处理第一段tmp = append(tmp, arr[h1])h1++}else {		// 两段都未结束if arr[h1] <= arr[h2]{tmp = append(tmp, arr[h1])h1++}else {tmp = append(tmp, arr[h2])h2++}}}for i:=0; i<length; i++{	// 将排序好两段合并写入arrarr[start+i] = tmp[i]}
}

0x06 快速排序

快速排序是东尼-霍尔发展来的一种排序算法。 平均状态下,排序n个项目要做O(nlogn)次比较,最坏情况下,要做O(n2)次比较,但是比较少见。事实上,快速排序通常明显比其他O(nlogn)算法速度要快,因为它的内部循环能够再大部分框架上很有效地被实现出来。

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

为什么快速排序比其他O(nlogn)排序算法快呢?

快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。

算法步骤:

  1. 选择一个基准
  2. 将比基准小的数放到基准左边,比基准大的数放到基准右边(相同的数可以放在任意一边)在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序
func QuickSort(arr []int) []int{return _QuickSort(arr, 0, len(arr)-1)
}func _QuickSort(arr []int, left int, right int) []int{if left < right{partitionIndex := Partition1Way(arr, left, right)// partitionIndex := Partition2Way(arr, left, right)_QuickSort(arr, left, partitionIndex-1)_QuickSort(arr, partitionIndex+1, right)}return arr
}

单路快排:从左向右遍历

// 快速排序--单路
func Partition1Way(arr []int, left int, right int) int{// 先分区,最后把基准换到边界上privot := leftindex := privot + 1for i := index; i<=right; i++{if arr[privot] > arr[i]{  // 当前值小于基准就交换,大于的不用管arr[index], arr[i] = arr[i], arr[index]index++   // 交换后的下一个}}// arr[index]是大于基准的arr[privot], arr[index-1] = arr[index-1], arr[privot]return index-1
}

双路快排:双指针从首尾向中间移动

// 快速排序--双路版
func Partition2Way(arr []int, low int, high int) int{tmp := arr[low]		// 基准for low < high{// 当队尾的元素大于等于基准数据时,向前挪动high指针for low < high && arr[high] >= tmp{high--}// 如果队尾元素小于tmp了,需要将其赋值给lowarr[low] = arr[high]// 当队首元素小于等于tmp时,向前挪动low指针for low < high && arr[low] <= tmp{low++}// 当队首元素大于tmp时,需要将其赋值给higharr[high] = arr[low]}// 跳出循环时low和high相等,此时的low或high就是tmp的正确索引位置// 由原理部分可以很清楚的知道low位置的值并不是tmp,所以需要将tmp赋值给arr[low]arr[low] = tmpreturn low
}

三路排序:分成小于区、等于区、大于区,不对等于区进行递归操作

// 快速排序--三路
func QuickSort3Way(arr []int) []int{// 确定分区位置return _QuickSort3Way(arr, 0, len(arr)-1)
}
func _QuickSort3Way(arr []int, left int, right int) []int{if left < right{lo, gt := Partition3Way(arr, left, right)_QuickSort3Way(arr, left, lo-1)_QuickSort3Way(arr, gt, right)}return arr
}
func Partition3Way(arr []int, left, right int) (int, int){key := arr[left]lo, gt, cur := left, right+1, left+1  // lo和gt是相等区左右边界for cur < gt{if arr[cur] < key{	// 小于key,移到前面arr[cur], arr[lo+1] = arr[lo+1], arr[cur]   // lo+1,保证最后arr[lo]小于keylo++	// 左边界右移cur++	// 能够确定换完之后该位置值小于key,}else if arr[cur] > key{arr[cur], arr[gt-1] = arr[gt-1], arr[cur]gt--	// 从后面换到前面,不知道是否比key的大,还要再比一下,所以cur不移动}else {cur++}}arr[left], arr[lo] = arr[lo], arr[left]   // 最后移动基准,arr[lo]一定比key小return lo, gt
}

0x07 堆排序

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

大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;
堆排序的平均时间复杂度为 Ο(nlogn)。

  1. 创建一个堆 H[0……n-1]
  2. 把堆首(最大值)和堆尾互换;
  3. 把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;
  4. 重复步骤 2,直到堆的尺寸为 1。
// 堆排序
func HeapSort(arr []int) []int{arrLen := len(arr)BuildMaxHeap(arr, arrLen)	// 初始化大顶堆for i:=arrLen-1; i>=0; i--{swap(arr, 0, i)    // 交换根节点和最后一个节点arrLen--heapify(arr, 0, arrLen)}return arr
}func BuildMaxHeap(arr []int, arrLen int){for i:=arrLen/2; i>=0; i--{heapify(arr, i, arrLen)}
}func heapify(arr []int, i, arrLen int){left := 2*i+1		// 左子right := 2*i+2		// 右子largest := i		// 当前最大值位置if left<arrLen && arr[left]>arr[largest]{largest = left}if right<arrLen && arr[right]>arr[largest]{largest = right}if largest != i{swap(arr, i, largest)	// 交换heapify(arr, largest, arrLen)  // 调整二叉树}
}func swap(arr []int, i, j int) {arr[i], arr[j] = arr[j], arr[i]
}

0x08 计数排序

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

  • 计数排序的特征
    当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 Θ(n + k)。计数排序不是比较排序,排序的速度快于任何比较排序算法。

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

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

算法的步骤如下:

(1)找出待排序的数组中最大和最小的元素
(2)统计数组中每个值为i的元素出现的次数,存入数组C的第i项
(3)对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
(4)反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

// 计数排序
func CountingSort(arr []int) []int{length := len(arr)maxValue := getMaxValue(arr)bucketLen := maxValue+1bucket := make([]int, bucketLen)sortedIndex := 0// 统计每个元素出现的个数for i:=0; i<length; i++{bucket[arr[i]] += 1}// 按照统计结果写入arrfor j:=0; j<length; j++{for bucket[j] > 0{arr[sortedIndex] = j   // bucket[j]的值是统计结果,后面会变化,j是真正值sortedIndex++bucket[j]--}}return arr
}
// 获得数组的最值差
func getMaxValue(arr []int) int{largest := math.MinInt32smallest := math.MaxInt32for i:=0; i<len(arr);i++{if arr[i] > largest{largest = arr[i]}if arr[i] < smallest{smallest = arr[i]}}maxValue := largest-smallestreturn maxValue
}

0x09 桶排序

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

在额外空间充足的情况下,尽量增大桶的数量
使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中
同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。

  1. 什么时候最快
    当输入的数据可以均匀的分配到每一个桶中。

  2. 什么时候最慢
    当输入的数据被分配到了同一个桶中。

  3. 示意图
    在这里插入图片描述

// 桶排序
func BucketSort(arr []int, bucketSize int) []int{// 获得arr的最值length := len(arr)maxNum, minNum := arr[0], arr[0]for i:=0; i<length; i++{if arr[i]>maxNum{maxNum = arr[i]}else if arr[i]<minNum{minNum = arr[i]}}maxValue := maxNum - minNum// 初始化桶bucketNum := maxValue/bucketSize + 1  // 桶个数buckets := make([][]int, bucketNum)for i:=0; i<bucketNum; i++{buckets[i] = make([]int, 0)}// 利用映射将元素分配到每个桶中for i:=0; i<len(arr); i++{id := (arr[i]-minNum)/bucketSize   // 桶IDbuckets[id] = append(buckets[id], arr[i])}// 对每个桶进行排序,然后按顺序将桶中数据放入arrarrIndex := 0for i:=0; i<bucketNum; i++{if len(buckets[i]) == 0{   // 空桶continue}InsertionSort2(buckets[i])    // 桶内排序for j:=0; j<len(buckets[i]); j++{	// 将每个桶的排序结果写入arrarr[arrIndex] = buckets[i][j]arrIndex++}}return arr
}

0x10 基数排序

基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

  • 基数排序 vs 计数排序 vs 桶排序
    这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:
    • 基数排序:根据键值的每位数字来分配桶;
    • 计数排序:每个桶只存储单一键值;
    • 桶排序:每个桶存储一定范围的数值;
  • 思路
    基数排序是按照低位先排序,然后收集;
    再按照高位排序,然后再收集;
    依次类推,直到最高位。
    有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。
    最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。
    在这里插入图片描述
// 基数排序
func RadixSort(arr []int, ) []int{maxn := maxBitNum(arr)		// arr最大位数dev := 1	// 除数,保证商最后一位是我们想要的mod := 10	// 模,取商的最后一位for i:=0; i<maxn; i++{		// 进行maxn次排序bucket := make([][]int, 10)	// 定义10个空桶result := make([]int, 0)	// 存储中间结果for _, v := range arr{n := v / dev % mod	// 取出对应位的值,放入对应桶中bucket[n] = append(bucket[n], v)}dev *= 10// 按顺序存入中间数组for j:=0; j<10; j++{result = append(result, bucket[j]...)}// 转存到原数组(结果)for k := range arr{arr[k] = result[k]}}return arr
}
// 获取数组的最大位数
func maxBitNum(arr []int) int{ret := 1count := 10for i:=0; i<len(arr); i++{for arr[i]>count{	// 对arr变化会修改内存里的值count *= 10		// 所以这里对count进行放大ret++}}return ret
}

总结

按时间复杂度分类:

  • O(n2):冒泡排序、选择排序、插入排序
  • O(nlogn):希尔排序、归并排序、快速排序、堆排序
  • O(n):计数排序、桶排序、基数排序

按稳定性分类

  • 稳定:冒泡排序、插入排序、归并排序、计数排序、桶排序、基数排序
  • 不稳定:选择排序、希尔排序、快速排序、堆排序

按排序方式

  • In-Place:冒泡排序、选择排序、插入排序、希尔排序、快速排序、堆排序
  • Out-Place:归并排序、计数排序、桶排序、基数排序

http://chatgpt.dhexx.cn/article/OGqjlQVJ.shtml

相关文章

排序算法——十大排序算法总结与对比

一、十大排序算法复杂度对比 二、关于排序算法的总结 1、基数排序仅仅适用于整型数的排序&#xff0c;一般不与另外的排序方法一起比较。 2、关于算法的稳定性&#xff1a;不稳定的算法有 “快希选堆”——快速排序&#xff0c;希尔排序&#xff0c;选择排序和堆排序。 3、关…

十大排序算法(面试必备)

目录 简单排序 1、冒泡排序 2、选择排序 3、插入排序 高级排序 4、希尔排序&#xff08;缩小增量排序&#xff09; 5、归并排序 6、快速排序 7、计数排序 8、堆排序 9、桶排序 10、基数排序 总结&#xff1a; 1、十大排序算法对比 2、基数排序、计数排序、桶排序…

十大排序算法学习

Sort 排序类算法是非常常见的算法&#xff0c;包括了比较类排序与非比较类排序 排序能够解决很多问题&#xff0c;有的编程语言也提供了一些排序算法函数&#xff08;比如C的sort&#xff09;但是掌握基本的排序算法原理以及写法仍然是很重要的&#xff0c;并且排序也是面试常…

十大排序算法(Java)

目录 1.冒泡排序 2.快速排序 3.插入排序 4.希尔排序 5.选择排序 6.堆排序 7.归并排序 8.计数排序&#xff1a;速度快&#xff0c;一般用于整数排序 9.桶排序 10.基数排序 1.冒泡排序 冒泡排序思路&#xff1a;&#xff08;两层for循环&#xff09; 比较相邻的元素。…

十大排序算法(C++)

十大排序算法Sorting algorithm(C) 百度百科&#xff1a; 所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。排序算法&#xff0c;就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地…

十大排序算法——C语言实现

1.冒泡排序 ​ 冒泡排序&#xff08;Bubble Sort&#xff09;也是一种简单直观的排序算法。它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换&#xff0c;也就是说该数…

Python实现十大排序算法

1.排序算法概述 非线性时间比较类排序&#xff1a;通过比较来决定元素间的相对次序&#xff0c;由于其时间复杂度不能突破O(nlogn)&#xff0c;因此称为非线性时间比较类排序。 线性时间非比较类排序&#xff1a;不通过比较来决定元素间的相对次序&#xff0c;它可以突破基于比…

Java实现十大排序算法

Java实现十大排序算法 十大排序算法分别为&#xff1a;选择排序、冒泡排序、插入排序、快速排序、归并排序、堆排序、希尔排序、桶排序、计数排序、基数排序。 本篇只是为了方便我在代码中直接复制调用&#xff0c;因此原理和思想解释的并不清楚&#xff0c;想看原理的朋友可…

十大排序算法(C++版)

十大排序算法 前言一、插入排序二、希尔排序三、冒泡排序四、快速排序五、选择排序六、归并排序七、堆排序八、计数排序九、桶排序十、基数排序总结 前言 什么是排序&#xff1f; 排序&#xff1a;将一组杂乱无章的数据按一定规律顺次排列起来。即&#xff0c;将无序序列排成一…

十大排序算法详解

十大排序算法详解 参考程序员必知必会的十大排序算法详解 引言 对于排序的分类&#xff0c;可以将排序算法分为两大类&#xff1a;基于比较和非比较的算法。 基于比较的排序算法可以细分为&#xff1a; 基于交换类&#xff1a;冒泡排序、快速排序基于插入类&#xff1a;直接插入…

JS 实现十大排序算法

文章目录 前言零、十大排序一、冒泡排序&#xff08;bubbleSort&#xff09;二、选择排序&#xff08;selectionSort&#xff09;三、插入排序&#xff08;insertSort&#xff09;四、希尔排序&#xff08;shellSort&#xff09;五、归并排序&#xff08;mergeSort&#xff09;…

十大经典排序算法Java版(动图演示)

文章目录 0 排序算法说明0.1 内部排序和外部排序0.2 比较类排序和非比较类排序0.3 关于时间复杂度0.4 关于稳定性0.5 名词解释&#xff1a; 1 交换排序——冒泡排序&#xff08;Bubble Sort&#xff09;1.1 什么时候最快1.2 什么时候最慢1.3 算法步骤1.4 动图演示1.5 Java实现 …

html之如何让button按钮居中

解决措施&#xff1a;使用center或者div的align属性 示例代码&#xff1a; <html> <body><center><button onClick"clickme()">hit me</button></center><script>function clickme(){alert("123");} </scr…

HTML中让表单和提交按钮居中的方法

表单&#xff1a; form{ width: 500px; /*设置宽度&#xff0c;方便使其居中*/ margin: 40px auto auto auto; /*上右下左*/ font-size: 25px; 提交按钮&#xff1a;div的align属性 <div align"center"><button onClick"clickme()">提交…

android中的Button按钮居中(水平垂直中)

今天发现一个很怪异的事 Android Studio中居然一个简单的按钮水品垂直居中都写不出来 下图为理想效果&#xff1a; 可是当我写原始出代码的时候&#xff08;如下&#xff09;&#xff1a; <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android&quo…

Vue组件居中:文字居中,按钮居中,图片居中等,如何实现在容器中居中

Vue实现组件在容器中居中显示的办法 本文用实验的方法理解各种方法实现居中的效果。 实现水平居中的样式主要有&#xff1a;text-align: center&#xff0c; margin: auto。 当然还有别的方式也可以实现&#xff0c;也会写在下面。 用三个同样的div来控制变量法看效果&#xf…

Contact form 7 提交按钮居中,怎么设置submit button居中显示

Contact form 7 提交按钮居中&#xff0c;怎么设置submit button居中显示 前言 最近公司在做网站&#xff0c;毫无疑问用的是wordpress程序&#xff0c;然后就用到了contact form 7这个插件。单是这个插件的按钮始终无法居中显示&#xff0c;查了很多教程有的让改主题&#x…

tkinter 让按钮居中显示

def ask(self, title, text, btn_comfirm_name"确定", btn_cancel_name"取消", wraplength400):self.master.title(title)tk.Label(self.middle, texttext, bg"#ffffff", wraplengthwraplength,justify"left").pack(pady15)self.botto…

html表单中按钮居中,Ant design StepsForm中如何使底部按钮居中

如图所示,当前有一个StepsForm表单,代码如下(基本就是官网的示例修改的)const Demo: React.FC = () => {const Option = [ {key: 1, value: 111, label: 个人 }, {key: 2, value: 222, label: 合作 }, ] const waitTime = (time: number = 100) => {return new Promise…

layui使按钮居中_button按钮居中的方法

今天在写页面时&#xff0c;发现给button按钮设置居中时&#xff0c;css页面写了text-align"center"&#xff0c;但是不起作用&#xff0c;用了display属性也无作用&#xff0c;试了好多次发现要给button按钮添加个p&#xff0c;然后让p居中就可以了。以下写个test来…