10.排序

一.冒泡排序

代码示例:

#将乱序列表中最大元素排列到列表末尾位置
def m_sort(alist):
    for j in range(0,len(alist)-1):
        if alist[j] > alist[j+1]:
            temp = alist[j]
            alist[j] = alist[j+1]
            alist[j+1] = temp
    return alist
def m_sort_final(alist):
    for i in range(0,len(alist)-1):
        for j in range(0,len(alist)-i-1):
            if alist[j] > alist[j+1]:
                temp = alist[j]
                alist[j] = alist[j+1]
                alist[j+1] = temp
    return alist

二.选择排序

 - 选择排序改进了冒泡排序,每次遍历列表只做一次交换。为了做到这一点,一个选择排序在他遍历时寻找最大的值,并在完成遍历后,将其放置在正确的位置。

def selectionSort(alist):
   for i in range(len(alist)-1,0,-1):
       positionOfMax=0
       for location in range(1,i+1):
           if alist[location]>alist[positionOfMax]:
               positionOfMax = location

       temp = alist[i]
       alist[i] = alist[positionOfMax]
       alist[positionOfMax] = temp

alist = [54,26,93,17,77,31,44,55,20]
selectionSort(alist)
print(alist)

  - 对于冒泡排序来讲选择排序由于交换数量的减少,选择排序通常在基准研究中执行得更快。

三.插入排序

  - 插入排序的主要思想是每次取一个列表元素与列表中已经排序好的列表段进行比较,然后插入从而得到新的排序好的列表段,最终获得排序好的列表。比如,待排序列表为[49,38,65,97,76,13,27,49],则比较的步骤和得到的新列表如下:(带有背景颜色的列表段是已经排序好的,红色背景标记的是执行插入并且进行过交换的元素)

 - step_1:

def sort(alist):
    i = 1
    if alist[i] < alist[i-1]:
        alist[i],alist[i-1] = alist[i-1],alist[i]

- step_2:

def sort(alist):
    i = 2
    while i > 0:
        if alist[i] < alist[i-1]:
            alist[i],alist[i-1] = alist[i-1],alist[i]
            i -= 1

- 完整代码:

def sort(alist):
    for i in range(1,len(alist)):
        while i > 0:
            if alist[i] < alist[i-1]:
                alist[i],alist[i-1] = alist[i-1],alist[i]
                i -= 1
            else:
                break
    return alist

 

 

 四.希尔排序

  - 希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本,该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量(gap)”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率比直接插入排序有较大提高。

- step_1:

def sort(alist):
    gap = len(alist) // 2
    #将插入排序当做增量为1的希尔排序
    for i range(1,len(alist)):
        while i > 0 :
            if alist[i] < alist[i-1]:
                alist[i],alist[i-1] = alist[i-1],alist[i]
                i -= 1
            else:
                break

- step_2:

def sort(alist):
    gap = len(alist) // 2
    #将增量设置成gap
    for i range(gap,len(alist)):
        while i > 0 :
            if alist[i] < alist[i-gap]:
                alist[i],alist[i-gap] = alist[i-gap],alist[i]
                i -= gap
            else:
                break

- 完整代码:

#继续缩小增量
def sort(alist):
    gap = len(alist) // 2
    while gap >= 1:
        #将增量设置成gap
        for i in range(gap,len(alist)):
            while i > 0 :
                if alist[i] < alist[i-gap]:
                    alist[i],alist[i-gap] = alist[i-gap],alist[i]
                    i -= gap
                else:
                    break
        gap //= 2
    return alist

 

五.归并排序

  - 归并排序采用分而治之的原理:

    - 将一个序列从中间位置分成两个序列;

    - 在将这两个子序列按照第一步继续二分下去;

    - 直到所有子序列的长度都为1,也就是不可以再二分截止。这时候再两两合并成一个有序序列即可。

      - 如何合并?

        下图中的倒数第三行表示为第一次合并后的数据。其中一组数据为 4 8  ,  5 7。该两组数据合并方式为:每一小组数据中指定一个指针,指针指向每小组数据的第一个元素,通过指针的偏移指定数据进行有序排列。排列情况如下:

      1. p1指向4,p2指向5,p1和p2指向的元素4和5进行比较,较小的数据归并到一个新的列表中。经过比较p1指向的4会被添加到新的列表中,则p1向后偏移一位,指向了8,p2不变。

      2.p1和p2指向的元素8,5继续比较,则p2指向的5较小,添加到新列表中,p2向后偏移一位,指向了7。

      3.p1和p2指向的元素8,7继续比较,7添加到新列表中,p2偏移指向NULL,比较结束。

      4.最后剩下的指针指向的数据(包含该指针指向数据后面所有的数据)直接添加到新列表中即可。

 

def merge_sort(alist):
    n = len(alist)
    #结束递归的条件
    if n <= 1:
        return alist
    #中间索引
    mid = n//2

    left_li = merge_sort(alist[:mid])
    right_li = merge_sort(alist[mid:])

    #指向左右表中第一个元素的指针
    left_pointer,right_pointer = 0,0
    #合并数据对应的列表:该表中存储的为排序后的数据
    result = []
    while left_pointer < len(left_li) and right_pointer < len(right_li):
        #比较最小集合中的元素,将最小元素添加到result列表中
        if left_li[left_pointer] < right_li[right_pointer]:
            result.append(left_li[left_pointer])
            left_pointer += 1
        else:
            result.append(right_li[right_pointer])
            right_pointer += 1
    #当左右表的某一个表的指针偏移到末尾的时候,比较大小结束,将另一张表中的数据(有序)添加到result中
    result += left_li[left_pointer:]
    result += right_li[right_pointer:]

    return result

alist = [3,8,5,7,6]
print(merge_sort(alist))

 六.快速排序

  • 将列表中第一个元素设定为基准数字,赋值给mid变量,然后将整个列表中比基准小的数值放在基准的左侧,比基准到的数字放在基准右侧。然后将基准数字左右两侧的序列在根据此方法进行排放。
  • 定义两个指针,low指向最左侧,high指向最右侧
  • 然后对最右侧指针进行向左移动,移动法则是,如果指针指向的数值比基准小,则将指针指向的数字移动到基准数字原始的位置,否则继续移动指针。
  • 如果最右侧指针指向的数值移动到基准位置时,开始移动最左侧指针,将其向右移动,如果该指针指向的数值大于基准则将该数值移动到最右侧指针指向的位置,然后停止移动。
  • 如果左右侧指针重复则,将基准放入左右指针重复的位置,则基准左侧为比其小的数值,右侧为比其大的数值。

- 第一次排序:将将比基准小的排列在基准左侧,比基准大的排列在基准右侧

def sort(alist):
    low = 0
    high = len(alist)-1
    #基准:最左侧的数值
    mid = alist[low]
    #low和high的关系只能是小于,当等于的时候就要填充mid了
    while low < high:
        while low < high:
            if alist[high] > mid:
                high -= 1
            else:
                alist[low] = alist[high]
                break
        while low < high:
            if alist[low] < mid:
                low += 1
            else:
                alist[high] = alist[low]
                break
        
        #当low和high重复的时候,将mid填充
        if low == high:
            alist[low] = mid #or alist[high] = mid  
            break
    return alist
    
    
    

- 完整代码:

def sort(alist,start,end):
    low = start
    high = end
    #递归结束的条件
    if low > high:
        return
    #基准:最左侧的数值
    mid = alist[low]
    #low和high的关系只能是小于,当等于的时候就要填充mid了
    while low < high:
        while low < high:
            if alist[high] > mid:
                high -= 1
            else:
                alist[low] = alist[high]
                break
        while low < high:
            if alist[low] < mid:
                low += 1
            else:
                alist[high] = alist[low]
                break
        
        #当low和high重复的时候,将mid填充
        if low == high:
            alist[low] = mid #or alist[high] = mid  
            break
    #执行左侧序列
    sort(alist,start,high-1)
    #执行右侧序列
    sort(alist,low+1,end)
    
    return alist
    
posted @ 2019-05-20 11:18  波晓张  阅读(1669)  评论(0编辑  收藏  举报