常用排序和查询

常用的排序和查询,以下用python实现

冒泡排序
原理:临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,这样一趟过去后,最大或最小的数字被交换到了最后一位,然后再从头开始进行两两比较交换,直到倒数第二位时结束.
时间复杂度o(n*n)

def bubble(l):
    flag = True
    for i in range(len(l)-1, 0, -1):
        if flag: 
            flag = False
            for j in range(i):
                if l[j] < l[j + 1]:
                    l[j], l[j+1] = l[j+1], l[j]
                    flag = True
        else:
            break
    print(l)

li = [21,44,2,45,33,4,3,67]
bubble(li)
选择排序
原理:从所有序列中先找到最小的,然后放到第一个位置;之后再看剩余元素中最小的,放到第二个位置……以此类推,直到完成整个的排序工作
时间复杂度o(n*n)
def selection_sort(list2):
    for i in range(0, len(list2)):
        min = i
        for j in range(i + 1, len(list2)):
            if list2[j] < list2[min]:
                min = j
        list2[i], list2[min] = list2[min], list2[i]

li = [21,44,2,45,33,4,3,67]
selection_sort(li)
print(li)
插入排序
原理:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应的位置并插入。
时间复杂度o(n*n)
def insertion_sort(list2):
    for i in range(1, len(list2)):
        save = list2[i]
        j = i
        while j > 0 and list2[j - 1] > save:
            list2[j] = list2[j - 1]
            j -= 1
        list2[j] = save

li = [21,44,2,45,33,4,3,67]
insertion_sort(li)
print(li)

#或者如下for循环:
def insertion_sort(list2):
    for i in range(1, len(list2)):
        save = list2[i]
        index = i
        for j in range(i,0,-1):
            if list2[j-1] > save:
                list2[j] = list2[j-1]
                #等这次循环结束之后,把index带出来
                index = j-1
            else:
                break
                #避免每次都是循环到j=0才结束
        list2[index] = save

li = [21,44,2,45,33,4,3,67]
insertion_sort(li)
print(li)
#对比发现while更容易理解,而且for循环是有问题的,因为第二个for循环中,每次都需要比较到index=0才结束,其实没必要这样,因为i之前的数据肯定是有序的,如果list2[j-1]<save,那么list2[j-1]之前的数据肯定也小于save;已经作了修正
#为什么不提倡用for,因为for是针对那种(0,len)的比较有优势,而插入排序的比较,不一定要到0

快速排序
快速排序采用的思想是分治思想。
快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。
递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。
时间复杂度: 平均o(nlogn), 最差o(n*n)

#把基准放到该放的位置
def sub_sort(array,low,high):
    key = array[low]
    while low < high:
        while low < high and array[high] >= key:
            high -= 1
        array[low] = array[high]
        while low <high and array[low] <= key: #这里可以去掉等号
            low += 1
        array[high] = array[low]
    array[low] = key
    return low

def quick_sort(array,low,high):
    if low < high:        
        key_index = sub_sort(array,low,high)
        quick_sort(array,low,key_index)
        quick_sort(array,key_index+1,high)

if __name__ == '__main__':
    array = [8,10,9,6,4,16,5,13,26,18,2,45,34,23,1,7,3]
    print(array)
    quick_sort(array,0,len(array)-1)
    print(array)
顺序查找
原理:顺序查找的原理很简单,就是遍历整个列表,逐个进行记录的关键字与给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的记录。如果直到最后一个记录,其关键字和给定值比较都不等时,则表中没有所查的记录,查找失败。
时间复杂度:O(n);

def SequenceSearch(array,t):
    len1 = len(array)
    for i in range(0, len1):
        if array[i] == t:
            print('the location of ',t,' is: ',i)
            return array[i]
    return -1

if __name__ == "__main__":
    a = [1,2,3,34,56,57,78,87]
    b = 57
    SequenceSearch(a, b)
二分法查找
二分法查找其实就是折半查找,一种效率较高的查找方法。针对有需数组来查找的。
主要思想是:(设查找的数组期间为array[low, high])
(1)确定该期间的中间位置K
(2)将查找的值T与array[k]比较。若相等,查找成功返回此位置;否则确定新的查找区域,继续二分查找。区域确定如下:
a.array[k]>T 由数组的有序性可知array[k,k+1,……,high]>T;故新的区间为array[low,……,K-1]
b.array[k]<T 类似上面查找区间为array[k+1,……,high]。每一次查找与中间值比较,可以确定是否查找成功,不成功当前查找区间缩小一半。递归找,即可。
时间复杂度:O(log2n);
def BinarySearch(array,t):
    low = 0
    height = len(array)-1
    while low < height:
        mid = int((low+height)/2)
        if array[mid] < t:
            low = mid + 1
        elif array[mid] > t:
            height = mid - 1
        else:
            print('the location of ',t,' is: ',mid)
            return array[mid]
    return -1

if __name__ == "__main__":
    a = [1,2,3,34,56,57,78,87]
    b = 57

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值