二分查找,ruby快排,归并,ruby实现

都是采用递归方法,针对有序数组。

以下代码,前者针对含有重复的有序数组,如【1,1,1,1,2,2,3,3,3,4,5,5,5,6】。查找最后一个值等于要查找的值。后者是普通的二分查找

 

# 二分查找 # 查找最后一个值等于给定值的元素 返回结果是数组的下标,不能直接返回值,因为重复值无法体现是否真正返回最后一个。
def half_find(array,value)
  if array.size <= 1
 return nil if array[0] && array[0] == value
 return nil
 end
 n = array.size / 2
 if value == array[n]
    res = half_find(array[n,array.size],value)
    return res if res
 return n
 end
 if value < array[n]
    half_find(array[0,n],value)
  else
 half_find(array[n,array.size],value)
  end
end
a=[]
(3..9).each do |i|
  a.append(i)
  a.append(i)
  a.append(i)
end

p = half_find(a,11)
p p
p a[p]


# 二分查找 # 查找第一个值等于给定值的元素
def half_find(array,value)
  if array.size <= 1
 return 0 if array[0] && array[0] == value
 return nil
 end
 n = array.size / 2
 return n if value == array[n]
  if value < array[n]
    half_find(array[0,n],value)
  else
 half_find(array[n,array.size],value)
  end
end

 

 

写了快排,再把另一个O(nlogn)时间复制度补上,空间复杂度为O(n),因此不常用。写了注释,帮助递归理解。

附上代码:

# 归并排序
def merge_sort(array)
  length = array.size
  return array if length <= 1

 n = length / 2

 left = merge_sort(array[0,n])

  right = merge_sort(array[n,length])

  merge(left,right)
end

# 先从左边找到最小单位,进行排序,再找左边的右边,再右边的左边,到右边的右边,最后左边与右边 (递归)
# 分治法典型
def merge(left,right)
  l ,r = 0,0
 result = []

  while l < left.size and r < right.size
    if left[l] < right[r]
      result.append(left[l])
      l+=1
 else
 result.append(right[r])
      r+=1
 end
 end
 result += left[l,left.size] if left[l,left.size].length > 0
 result += right[r,right.size] if right[r,right.size].length > 0
 result
end

aa = merge_sort([7,6,5,4,3,2,1])
p aa

 

 

 

 最近复习了快排,还没用过ruby实现快排,因此动手去做了实现。顺便也网上查了下百度给的代码,是未优化的且对原排序数组有改动,因此动手实现一个优化快排。

 

   话不多说,上代码:(ps: 可复制粘贴校准代码正确性,如有错误,望指出,O(∩_∩)O谢谢)

 

    

# 稳定快排优化代码--ruby --下标排序 适用于各场景排序
def index_quick_sort(array)
  # 递归终点
 return array if array.length <= 1
 # 选取随机下标,rand针对区间/某个数,sample针对数组,因此这里选前者更适合
 random_num = rand(array.length)
  # 准备数组
 less_array = []
 greater_array = []
  # 注意,这里的@array是实例变量,array是局部变量
 # 因为每次都要生成一个新数组,所以局部变量恰好适合
 (0..array.length-1).each do |i|
    next if i == random_num
 if array[i] < array[random_num]
      less_array.append(array[i])
      next
 end
 if array[i] > array[random_num]
      greater_array.append(array[i])
      next
 end
 if array[i] == array[random_num] && i < random_num #这里处理不稳定性,加上该段代码保证排序稳定
 less_array.append(array[i])
    else
 greater_array.append(array[i])
     end
 end
 quick_sort(less_array) + [array[random_num]] + quick_sort(greater_array)
 end

 
# 不稳定快排优化代码--ruby --值排序 对重复值的顺序不在意的话可以考虑,在大量数据且多重复时,性能远远大于稳定快排
def value_quick_sort(array)
  return array if array.size <= 1
 # 选取随机值,rand针对区间/某个数,sample针对数组,因此这里选前者更适合
 random_value = array.sample
  n = array.count(random_value)
  value_quick_sort(array.select { |i|  i < random_value}) + [random_value]*n + value_quick_sort(array.select { |i|  i > random_value})
end



# 下标结合值 稳定快排,还有优化的地方,待完善,在大量数据且多重复时,性能远远大于稳定快排,数据重复越多,性能提升越大!
def index_value_quick_sort(array)
  # 递归终点
 return array if array.length <= 1
 # 选取随机下标,rand针对区间/某个数,sample针对数组,因此这里选前者更适合
 random_num = rand(array.length)
 value = array[random_num]
 n = array[0,random_num+1].count(value)
 m = 0
 p = 0
 # (i == value && i.object_id > value_object_id) 内存地址可否排序?待考虑,重复select,待优化
 index_value_quick_sort(array.select { |i|  i < value }) + array.select { |i| i if (i == value && (m += 1) && m < n) } + [value] + array.select { |i| i if (i == value && (p += 1) && p > n) } + index_value_quick_sort(array.select { |i|  i > value})
end



# 网上百度百科ruby代码,稳定排序算法,未优化,默认取最后值进行快排,且会修改原数组
def quick_sort(a)
 (x=a.pop) ? quick_sort(a.select { |i| i <= x }) + [x] + quick_sort(a.select { |i| i > x }) : []
end

 
s1=[1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 5, 6, 7, 8, 25, 54, 54, 67, 96].size
s2=[1, 1, 2, 2, 3, 3, 3, 4, 5, 6, 7, 8, 25, 54, 54, 67, 96].size

[1, 1, 2, 2, 3, 3, 3, 4, 5, 6, 7, 8, 25, 54, 54, 67, 96]
a=[2,1,3,2,54,3,6,7,5,4,8,96,67,54,3,25,1,2,2,2,2]*299

p a.length

t= (Time.now)
bb = index_value_quick_sort(a)
p bb
t1=(Time.now)
p t1 - t

t=(Time.now)
aa = index_quick_sort(a)
p aa
t1=(Time.now)
p t1 - t

p aa.length
p bb.length
p a.size
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值