常用排序和查询

来源:互联网 发布:java pop3 编辑:程序博客网 时间:2024/06/05 00:17

常用的排序和查询,以下用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] = saveli = [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] = saveli = [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 lowdef 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 -1if __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 -1if __name__ == "__main__":    a = [1,2,3,34,56,57,78,87]    b = 57

0 0