python算法【】

冒泡

思想:每次比较相邻的两个值,将最大的值(升序)或最小(降序)的推向最前面

最终效果:把当前序列的最大值交换到最后一个位置

  • 最优时间复杂度:O(n) (升序排列,序列已经处于升序状态)
  • 最坏时间复杂度:O(n**2)
  • 稳定性:稳定

代码:

 1 def bubble(alist):
 2     a_len = len(alist)
 3 
 4     for i in range(a_len-1, 0, -1):
 5         middle = True
 6         for j in range(0, i):
 7             if alist[j] > alist[j+1]:
 8                 alist[j+1], alist[j] = alist[j], alist[j+1]
 9                 middle = False
10         if middle:
11             break
12 
13 
14 def main():
15     alist = [1, 65, 33, 86, 13, 13, 45, 28, 55]
16     print('排序前{}'.format(alist))
17     bubble(alist)
18     print('排序后{}'.format(alist))
19 
20 
21 if __name__ == "__main__":
22     main()
View Code

 

 1 def bubble(alist):
 2     a_len = len(alist)
 3 
 4     for i in range(a_len-1):
 5         middle = True
 6         for j in range(0, a_len-i-1):
 7             if alist[j] > alist[j+1]:
 8                 alist[j], alist[j+1] = alist[j+1], alist[j]
 9                 middle = False
10         if middle:
11             break
12 
13 
14 def main():
15     alist = [1, 65, 33, 86, 13, 13, 45, 28, 55]
16     print('排序前{}'.format(alist))
17     bubble(alist)
18     print('排序后{}'.format(alist))
19 
20 
21 if __name__ == "__main__":
22     main()
View Code

选择

思想:在没有排序的序列中找到最小的元素,然后放到序列的起始位置

核心理解:选择当前序列的最小值置于第一个位置,用一个元素和序列后面所有元素进行比较小的置于一个位置 

最差时间复杂度: (n-1)+(n-2).......1 ((n-1)+1)//2 * (n-1)    时间复杂度为:O(n**2)

最优时间复杂度 O(n**2)

稳定性:不稳定

代码:

 1 def select_sort(alist):
 2     a_len = len(alist)
 3 
 4     for i in range(a_len-1):
 5         middle = i
 6         for j in range(i+1, a_len):
 7             if alist[j] < alist[middle]:
 8                 middle = j
 9         if i != middle:
10             alist[i], alist[middle] = alist[middle], alist[i]
11 
12 
13 def main():
14     alist = [1, 65, 33, 86, 13, 13, 45, 28, 55]
15     print('排序前{}'.format(alist))
16     select_sort(alist)
17     print('排序后{}'.format(alist))
18 
19 
20 if __name__ == "__main__":
21     main()
View Code

插入

思想:把序列看成两部分,一部分是有序一部分是无序       最开始,把序列的第一个元素看做有序序列

关键点:如何插入到前面的有序序列中,从无序列表中取一个数据依次向前和有序序列的元素比较,如果小则向前

最差时间复杂度: (n-1)+(n-2).......1 ((n-1)+1)//2 * (n-1)    时间复杂度为:O(n**2)

最优时间复杂度:O(n)

稳定性:稳定

代码:

def insert_sort(alist):
    a_len = len(alist)
    for i in range(a_len):
        for j in range(i, 0, -1):
           if alist[j] < alist[j-1]:
               alist[j], alist[j-1] = alist[j-1], alist[j]
           else:
               break


def main():
    alist = [1, 65, 33, 86, 13, 13, 45, 28, 55]
    print('排序前{}'.format(alist))
    insert_sort(alist)
    print('排序后{}'.format(alist))


if __name__ == "__main__":
    main()
View Code

希尔

思想:把整个序列取一个缝隙  gap取一个数据,最终整个序列分成gap个子序列,分别对每个子序列进行插入排序   不断将gap值除二  直到为1时暂停

最差时间复杂度: (n-1)+(n-2).......1 ((n-1)+1)//2 * (n-1)    时间复杂度为:O(n**2)

最优时间复杂度:跟gap取值有关系  O(n^1.3)

稳定性:不稳定

代码:

def shell_sort(alist):
    # 遍历步长对应元素之后的所有元素,,对每个元素之前的序列进行排序(注意比较元素不是前一个,而是当前元素减去gap值)
    # 取一个gap值,,为步长,将序列分成gap份,然后对每个序列进行插入排序
    a_len = len(alist)

    gap = a_len // 2

    while gap > 0:
        for i in range(gap, a_len):
            j = i
            while j >= gap and alist[j] < alist[j-gap]:
                alist[j], alist[j-gap] = alist[j-gap], alist[j]
                j -= gap
        gap //= 2


def main():
    alist = [1, 65, 33, 86, 13, 13, 45, 28, 55]
    print('排序前{}'.format(alist))
    shell_sort(alist)
    print('排序后{}'.format(alist))
    pass


if __name__ == "__main__":
    main()


if __name__ == "__main__":
    main()
View Code

 快速排序

代码及思想:

 1 def query_sort(alist, start=None, end=None):
 2     """实现快速排序
 3     思想:首先定义一个基准(一般开始为基准),两个游标,(游标为:序列的起始下标和终止下标,)然后
 4         拿基准和终止游标对应的值比较:
 5             如果终止游标对应的值比基准小则将终止游标对应值赋值给起始下标对应的值
 6                 然后:移动前面的游标,指向新的值后再与基准对比
 7                     如果大于基准,将值赋给终止下标对应的值
 8                     如果 小于基准移动前面的游标
 9             如果:后边的值比基准大:则将后面的游标前前移动
10         (以此类推将可以得到基准的准确位置,再以基准的准确位置分成两部分执行以上的操作)
11         注意:
12             排序过程时,序列中有两个索引(除第一次的比较)对应的值为同一个值:
13             当两个游标碰撞时当前位置则为基准的位置
14             所以外循环的停止条件为:当两个游标相遇时停止
15     """
16     if start is None or end is None:
17         start = 0
18         end = len(alist) - 1
19 
20     if start >= end:
21         return
22 
23     base_num = alist[start]
24 
25     left_index = start
26     right_index = end
27 
28     while left_index < right_index:
29         if alist[right_index] < base_num:
30             alist[left_index] = alist[right_index]
31             left_index += 1
32             while left_index < right_index:
33                 if alist[left_index] > base_num:
34                     alist[right_index] = alist[left_index]
35                     right_index -= 1
36                     break
37                 else:
38                     left_index += 1
39         else:
40             right_index -= 1
41 
42     alist[left_index] = base_num
43     #
44     query_sort(alist, start=start, end=left_index-1)
45     #
46     query_sort(alist, start=right_index+1, end=end)
47 
48 
49 def main():
50     alist = [37, 65, 33, 86, 13, 13, 45, 12, 28, 55]
51     print('排序前{}'.format(alist))
52     query_sort(alist)
53     print('排序后{}'.format(alist))
54     pass
55 
56 
57 if __name__ == "__main__":
58     main()
View Code

稳定性:不稳定

时间复杂度

  • 最坏时间复杂度:当为有序序列时为最坏情况  每轮比较n-1次,,比较n轮  O(n**2)
  • 最优时间复杂度:每次对半的时候为最优时间复杂度:logn*(n-1)----》O(nlogn)

归并排序

代码

def guibin_sort(alist):
    # 判停条件
    if len(alist) <= 1:
        return alist
    # 将列表分成两半
    a_len = len(alist)//2
    l_list = guibin_sort(alist[a_len:])
    r_list = guibin_sort(alist[:a_len])

    # 定义每个列表的起始页
    l_index = 0
    r_index = 0

    # 创建新列表  将元素,添加到列表当中
    new_list = []
    
    # 逐个比较两个列表当中值,将较小值添加到列表当中  当有一个列表为空时,将另一个列表与new_list合并即可
    
    while 1:
        if l_list[l_index] < r_list[r_index]:
            new_list.append(l_list[l_index])
            l_index += 1
        else:
            new_list.append(r_list[r_index])
            r_index += 1

        if len(l_list[l_index:]) == 0 or len(r_list[r_index:]) == 0:
            break
    
    new_list += l_list[l_index:]
    new_list += r_list[r_index:]

    return new_list


def main():
    alist = [37, 65, 33, 86, 13, 38, 13, 45, 12, 28, 55]
    print('排序前{}'.format(alist))
    print(guibin_sort(alist))
    pass

if __name__ == "__main__":
    main()
归并Code

最优/最差时间复杂度:O(nlogn)  

稳定性:向上合并时可以人为的控制

二分查找

 

posted @ 2017-09-03 23:22  凯哥吧  阅读(94)  评论(0编辑  收藏  举报