整理的排序算法

Posted wang-kai-1994

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了整理的排序算法相关的知识,希望对你有一定的参考价值。

1. 冒泡排序

# 冒泡排序
b = [9, 8, 7, 6, 5, 4]


class BubbleSort(object):
    ‘‘‘
    self.datas:       要排序的数据列表
    self.datas_len:   数据急的长度
    _sort():          排序函数
    
    冒泡排序要排序n个数,由于每遍历一趟只排好一个数字,
    则需要遍历n-1趟,所以最外层循环要循环n-1次。
    内层的循环完成一次,代表归位完成一个数字。因为把内层的数字循环一遍。
    基于每归位完成一个数字,循环次数就要-1,因此内层的循环次数要减去外层循环的当前完成次数。
    比如外层完成1次,内层实际上完成一遍循环,因此有一个数已经归位,所以下次的内层循环就不用对归位好的数排序。
    所以内层循环的次数要-1,而这也对应着外层的循环次数。
    ‘‘‘

    def __init__(self, datas):
        self.datas = datas
        self.datas_len = len(datas)

    def _sort(self):
        
        for i in range(self.datas_len - 1):        # 循环的总次数
        
            for j in range(self.datas_len - 1 - i):        # 里层循环完成归位一个数
            
                if (self.datas[j] > self.datas[j + 1]):        # 判断的条件
                
                    self.datas[j], self.datas[j + 1] = self.datas[j + 1], self.datas[j]
                    
                    print(self.datas)    # 打印循环中的结果,直至完成


a = BubbleSort(b)
a._sort()

 

2. 选择排序

s = [3, 4, 1, 6, 2, 9, 7, 0, 8, 5]

for i in range(0, len(s) - 1):      # 根据列表的长度限定循环的范围
    index = i                        # 对应当前循环次数的下标
    for j in range(i + 1, len(s)):    # 起始位置是里层循环完成的当前次数+1,末位置根据起始位置而变化
        if s[index] > s[j]:
            index = j                # index取当前最大数的下标
    s[i], s[index] = s[index], s[i]    # 交换当前循环次数和最大数的下标
    print(s)                        

print(s)

 

3. 插入排序

L = [89, 67, 56, 45, 34, 23, 1]
‘‘‘
这段代码的思想就是,从起始的两个数进行比较,起始数为1,和前面的数进行比较。
如果起始数比前面的数小,那么两个数都变成前面的数也就是较大的那个数。。否则进入下一次比较。
一次内循环结束之后,交换起始数较小的数和最终变化的较大数。
‘‘‘


def direct_insert_sort(numbers):
    for i in range(1, len(numbers)):  # temp变量指向尚未排好序元素(从第二个开始)

        temp = numbers[i]
       
        j = i - 1             # j指向前一个元素的下标
        
        while j >= 0 and temp < numbers[j]:
                                 # temp与前一个元素比较,若temp较小则前一元素后移,j自减,继续比较
            numbers[j + 1] = numbers[j]

            j = j - 1                # 结束循环的条件
                           
        numbers[j + 1] = temp         # temp所指向元素的最终位置


if __name__ == __main__:
    direct_insert_sort(L)

    print(L)

 

4 希尔排序

def ShellInsetSort(array, len_array, dk):  # 直接插入排序
    
    for i in range(dk, len_array):  # 从下标为dk的数进行插入排序
        position = i
        current_val = array[position]  # 要插入的数

        index = i
        j = int(index / dk)  # index与dk的商,
        index = index - j * dk  # 不能整除index就等于 当前值 - 增量,否则为0

        # position>index,要插入的数的下标必须得大于第一个下标

        while position > index and current_val < array[position-dk]:
            array[position] = array[position-dk]  # 后移
            position = position-dk
        else:
            array[position] = current_val
            
        ‘‘‘如果下标数大的数 < 下标数小的数,先把下标数小的数赋值给下标数大的数或者说数值大的数赋值数值小的数,
        然后把较大数的下标减去增量,即得到赋值数的下标,因为下标数大的数之前定义过,所以把改变后的数赋值给这个数
        假设 a的下标为1, 数值为3, 
            要插入的数 b 的下标为3, 数值为1,且 b 赋值给 temp,增量为2即下标相减的绝对值
            对比后把a的值赋值给b,即3,
            再把b的下标减去增量,得到1,temp 赋值 数组下标为1(即a的下标)的数
            完成一次插入
        ‘‘‘


def ShellSort(array, len_array):  # 希尔排序
    dk = int(len_array/2)  # 增量
    while(dk >= 1):
        ShellInsetSort(array, len_array, dk)
        print(">>:",array)
        dk = int(dk/2)        # 一次循环之后改变增量

if __name__ == "__main__":
    array = [49, 38, 65, 97, 76, 13, 27, 49, 55, 4]
    print(">:", array)
    ShellSort(array, len(array))

 

5. 快速排序

def QuickSort(myList, start, end):
    # 判断low是否小于high,如果为false,直接返回
    if start < end:
        i, j = start, end
        # 设置基准数
        base = myList[i]

        while i < j:
            # 如果列表后边的数,比基准数大或相等,则前移一位直到有比基准数小的数出现
            while (i < j) and (myList[j] >= base):
                j = j - 1

            # 如找到,则把第j个元素赋值给第个元素i,此时表中i,j个元素相等
            myList[i] = myList[j]

            # 同样的方式比较前半区
            while (i < j) and (myList[i] <= base):
                i = i + 1
            myList[j] = myList[i]
        # 做完第一轮比较之后,列表被分成了两个半区,并且i=j,需要将这个数设置回base
        myList[i] = base

        # 递归前后半区
        QuickSort(myList, start, i - 1)
        QuickSort(myList, j + 1, end)
    return myList


myList = [49, 38, 65, 97, 76, 13, 27, 49]
print("Quick Sort: ")
QuickSort(myList, 0, len(myList) - 1)
print(myList)

 

6 归并排序

def merge_sort(li):
    # 不断递归调用自己一直到拆分成成单个元素的时候就返回这个元素,不再拆分了
    if len(li) == 1:
        return li

    # 取拆分的中间位置
    mid = len(li) // 2
    # 拆分过后左右两侧子串
    left = li[:mid]
    right = li[mid:]

    # 对拆分过后的左右再拆分 一直到只有一个元素为止
    # 最后一次递归时候ll和lr都会接到一个元素的列表
    # 最后一次递归之前的ll和rl会接收到排好序的子序列
    ll = merge_sort(left)
    rl = merge_sort(right)

    # 我们对返回的两个拆分结果进行排序后合并再返回正确顺序的子列表
    # 这里我们调用拎一个函数帮助我们按顺序合并ll和lr
    return merge(ll, rl)


# 这里接收两个列表
def merge(left, right):
    # 从两个有顺序的列表里边依次取数据比较后放入result
    # 每次我们分别拿出两个列表中最小的数比较,把较小的放入result
    result = []
    while len(left) > 0 and len(right) > 0:
        # 为了保持稳定性,当遇到相等的时候优先把左侧的数放进结果列表,因为left本来也是大数列中比较靠左的
        if left[0] <= right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0))
    # while循环出来之后 说明其中一个数组没有数据了,我们把另一个数组添加到结果数组后面
    result += left
    result += right
    return result


if __name__ == __main__:
    li = [5, 4, 3, 2, 1]
    li2 = merge_sort(li)
    print(li2)

 

7. 二分查找

def binary_search(find_num,nums):

    print(nums)
    
    if len(nums) == 0:
    
        print(False)
        
        return

    mid_index = len(nums) // 2          
    
    if find_num > nums[mid_index]:      #比较输入的值和中间的值
    
        nums_1=nums[mid_index+1:]       #保留nums[mid_index+1:]之后的内容
        
        binary_search(find_num,nums_1)        # 递归调用
        
    elif find_num < nums[mid_index]:
    
        nums_1=nums[:mid_index]

        binary_search(find_num,nums_1)        # 递归调用
        
    else:
        print(True)
        
binary_search(81,ums)

 

以上是关于整理的排序算法的主要内容,如果未能解决你的问题,请参考以下文章

各种排序算法整理(附带习题及代码)

排序算法整理(啊哈算法)

内排序算法的整理

[编程 | Phthon | 02] Python3常用算法整理

Java排序算法 - 堆排序的代码

快速排序思路整理