数据结构与算法 排序与搜索(二)

一、 排序

(一)希尔排序

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
希尔排序的基本思想是:将数组列在一个表中并对列分别进行插入排序,重复这过程,不过每次用更长的列(步长更长了,列数更少了)来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身还是使用数组进行排序。
在这里插入图片描述
其代码实现如下:

def shell_sort(alist):
	"""希尔排序"""
    n = len(alist)
    gap = int(n / 2)#gap为步长
    while gap > 0:
        for i in range(gap, n):
            j = i
            while j >= gap and alist[j - gap] > alist[j]:
                alist[j - gap], alist[j] = alist[j], alist[j - gap]#同列之间比较大小,交换位置
                j -= gap
        gap = int(gap / 2)
    print(alist)


list = [1, 3, 2, 7, 5, 9, 4]
shell_sort(list)

(二) 归并排序

归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。

将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。

def merge_sort(alist):
    n = len(alist)
    if n <= 1:
        return alist
    num = int(n / 2)
    # 分解
    left = merge_sort(alist[:num])
    right = merge_sort(alist[num:])
    return merge(left, right)


def merge(left, right):
    """合并"""
    l, r = 0, 0
    result = []
    while l < len(left) and r < len(right):
        if left[l] < right[r]:
            result.append(left[l])
            l += 1
        else:
            result.append(right[r])
            r += 1
    result += left[l:]
    result += right[r:]
    # print(result)
    return result
alist = [54,26,93,17,77,31,44,55,20]
sorted_alist = merge_sort(alist)
print(sorted_alist)

二、搜索

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
在这里插入图片描述

(一)不含递归的二分法

def bin_search(alist, item):
    alist = merge_sort(alist)# 此处调用了归并排序函数,将无序列表转为有序。若不调用,则输入的列表必须为有序
    first = 0
    last = len(alist) - 1#列表从0开始,故需减一
    while first < last:
        mid = int((first + last) / 2)#中间点
        if alist[mid] == item:
            return True
        elif alist[mid] < item:
            first = mid + 1#因为是有序表,故可确定前半段无我们要找的元素
        else:
            last = mid - 1
    return False


list = [8, 1, 3, 2, 7, 5, 9, 4, 6]
print(bin_search(list, 8))

(二)含递归的二分法

def bin_search(alist, item):
    if len(alist) == 0:#alist的长度在递归下不断减小,减小至0时可判断无要找的元素
        print("%d is not in the list!" % item)
    else:
        mid_point = len(alist) // 2#确定中间点
        if alist[mid_point] == item:
            print("%d is in the list!" % item)#中间点恰好为我们找的元素
        elif alist[mid_point] < item:
            return bin_search(alist[mid_point + 1:], item)#递归调用,此时调用函数的alist为列表后半段
        else:
            return bin_search(alist[:mid_point], item)#递归调用,此时调用函数的alist为列表前半段


test_list = [1, 2, 3, 4, 5, 6, 7]
bin_search(test_list, 7)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值