基于fortran的TimSort排序算法,最快的排序算法
![](https://img-blog.csdnimg.cn/direct/d1a0fd0e5e2444fb84df66f2bd8bb220.png)
0. 引言
Timsort
是一种混合排序算法,它结合了插入排序和归并排序的思想。它由Tim Peters在2002年为Python编程语言开发而来,并被应用于Java的Arrays.sort方法和Python的sorted函数中。
Timsort
的基本原理如下:
1. 首先将要排序的数组分割成大小相等的块,这些块被称为run。每个run都可以使用插入排序进行排序。
2. 排序后的run会被合并成更大的run,直到所有的run都被合并为一个run。合并操作使用归并排序的方式进行。
3. 为了提高效率,Timsort使用了一种优化的合并策略,称为galloping mode(飞跃模式)。当两个run进行合并时,如果其中一个run的元素在另一个run中都找不到比它小的元素,那么可以直接将整个run复制到目标数组中,而不需要逐个比较和复制元素。这种策略可以显著提高排序效率。
4. 在合并的过程中,Timsort还会根据已经排序好的块的大小选择合适的合并方式。比如,当合并两个run时,如果其中一个run的长度是另一个run的2倍以上,那么可以直接将较短的run插入到较长的run的合适位置,而不需要使用归并排序。
Timsort
的时间复杂度为O(n log n),其中n是要排序的元素的个数。它的性能在实际应用中表现良好,尤其是对于有序或部分有序的数组。
总结起来,Timsort
是一种结合了插入排序和归并排序思想的排序算法。它使用分块、合并和优化的合并策略来提高排序效率。
1. 代码实现及示例
生成一个随机一维向量,调用module
文件下的timSort函数
进行排列,timSort函数
的一般形式为:
subroutine timSort(arr)
其中,arr
为输入输出(inout)变量,输出的即为排序后的结果。下面是timSort
排序算法示例:
! test timSort
program main
use, intrinsic :: iso_fortran_env
use base_math
real(real64),allocatable :: array(:),array2(:),array3(:)
real(real64) :: t_beg,t_end,t_sample
integer(int32) :: i
allocate( array(12) ) ! 假定数组长度为12
call random_seed
call random_number(array) ! 生成随机数组
array3 =array
call cpu_time(t_beg)
call timSort(array3)
call cpu_time(t_end)
t_Tim = t_end - t_beg
print *," 排序前 "," 排序后"
do i = 1, size(array)
write(*, '(f12.7,1X,f12.7,1X,f12.7)')array(i),array3(i)
enddo
end program
执行结果如下,能够看到array
和array3
分别为排序前和排序后的数组。在排序数组长度较长是,也具有较好的效率,可以说是目前最高效的排序算法。
![](https://i-blog.csdnimg.cn/direct/b9b852d469424ef7bf93ff7e2e943ff0.png)
下面是module
文件,包含timSort
排序算法的主要过程。
module base_math
use, intrinsic :: iso_fortran_env
implicit none
contains
subroutine insertionSort(arr, left, right)
implicit none
real(real64),intent(inout) :: arr(0:)
integer(int32),intent(in) :: left,right
integer(int32) :: i,j
real(real64) :: temp
do i = left + 1, right
temp = arr(i)
j = i - 1
do while (j >= left)
if( arr(j) <= temp )exit
arr(j+1) = arr(j)
j = j-1
enddo
arr(j+1) = temp
enddo
end subroutine insertionSort
subroutine merge(arr, l, m, r)
implicit none
real(real64),dimension(0:) :: arr
integer(int32) :: l,m,r
integer(int32) :: len1,len2,i,j,k
real(real64),allocatable,dimension(:) ::left,right
len1 = m - l + 1
len2 = r - m
allocate(left(0:len1-1))
allocate(right(0:len2-1))
do i = 0, len1-1
left(i) = arr(l + i)
enddo
do i = 0, len2-1
right(i) = arr(m + 1 + i)
enddo
i = 0
j = 0
k = l
do while (i < len1 .and. j < len2)
if (left(i) <= right(j))then
arr(k) = left(i)
i = i + 1
else
arr(k) = right(j)
j = j+1
endif
k = k + 1
enddo
do while (i < len1)
arr(k) = left(i)
k = k + 1
i=i+1
enddo
do while (j < len2)
arr(k) = right(j)
k = k +1
j = j +1
enddo
end subroutine
! 排序算法
subroutine timSort(arr)
implicit none
real(real64),dimension(0:) :: arr
integer(int32) :: i,size1,left,mid,right,n
integer(int32),parameter :: minRun = 32
n = size(arr)
!minRun = calcMinRun(n)
do i = 0, n-1, minRun
call insertionSort(arr, i, min((i+minRun-1),(n-1)))
enddo
size1 = minRun
do while(size1 < n)
do left = 0,n,2 * size1
mid = min(n - 1, left + size1 - 1)
right = min((left + 2 * size1 - 1), (n - 1))
if (mid < right)then
call merge(arr, left, mid, right)
endif
enddo
size1 = 2 * size1
enddo
end subroutine timSort
end module base_math
2. 排序算法执行效率对比
前篇已介绍过简单排序算法和快速排序算法,那加上本篇的timSort
算法,三种排序算法效率如何❓下面模拟一个chang数组进行排序并计时,可以直观3种算法的效率。
program main
use, intrinsic :: iso_fortran_env
use base_math
! 效率对比
real(real64),allocatable :: array(:),array2(:),array3(:)
integer :: i
integer(int32) :: t_beg,t_end,t_sample,t_quick,t_Tim
real(real64),allocatable,dimension(:) :: arr
allocate( array(100000) ) ! 假定数组长度为32
call random_seed
call random_number(array) ! 生成随机数组
call system_clock(t_beg)
array2 = sort_simple(array)
call system_clock(t_end)
t_sample = t_end - t_beg
array3 =array
call system_clock(t_beg)
call timSort(array3)
call system_clock(t_end)
t_Tim = t_end - t_beg
call system_clock(t_beg)
call QuickSort(array) !> 快速排序
call system_clock(t_end)
t_quick = t_end - t_beg
print *,"排序耗时对比:"
print *,"sample=",t_sample,"quick=",t_quick,"t_Tim=",t_Tim
print *,""
print *,"数组array排序结果:"
do i = 1, 100
write(*, '(f12.7,1X,f12.7,1X,f12.7)')array2(i),array(i),array3(i)
enddo
end program
对比发现,quickSort
排序算法与TimSort
算法运行效率相差不大,整体TimSort
稍微快些,可能存在写法问题不能真实反应运行效率,这里仅做为示例,后续有机会再对TimSort算法做一些优化再进行比较。
3. 代码实现及示例
本篇分享了fortran
代码写的TimSort
排序算法,能够实现对一维向量的正确排列。
😜
😜😜
😜😜😜😜