zoukankan      html  css  js  c++  java
  • 【程序员笔试面试必会——排序①】Python实现 冒泡排序、选择排序、插入排序、归并排序、快速排序、堆排序、希尔排序

    最近在准备笔试题和面试题,把学到的东西整理出来,一来是给自己留个笔记,二来是帮助大家学习。

     

    题目:

    给定一个int数组A及数组的大小n,请返回排序后的数组。  

    测试样例: 
    输入:[1,2,3,5,2,3],6
    返回:[1,2,2,3,3,5]

    代码示例:

    冒泡排序:O(n^2)

      最基本的排序,不多解释。

    class BubbleSort:
        def bubbleSort(self, A, n):
            for x in xrange(n):
                for y in xrange(n-x-1):
                    if A[y] > A[y+1]:
                        A[y], A[y+1] = A[y+1], A[y]
            return A

    选择排序:O(n^2)

      想象成每次从一大堆数里面选出最小的数放在左边,重复直到这一大对数都被选完。

    class SelectionSort:
        def selectionSort(self, A, n):
            for i in xrange(n-1):
                min_index = i
                for j in xrange(i+1, n):
                    if A[min_index] > A[j]:
                        min_index = j
                if min_index != i:
                    A[i], A[min_index] = A[min_index], A[i]
            return A

    插入排序:O(n^2)

      想象成打麻将时,摸到一个排插入到已有的麻将里边。选择排序从左边第二个牌开始,与左边的牌比较,如果比左边的小就与其交换位置,依次重复此步骤,直到排序完所有的牌。

    class InsertionSort:
        def insertionSort(self, A, n):
            for i in xrange(1, n):
                tmp = A[i]
                j = i - 1
                while tmp < A[j] and j >= 0:
                    A[j+1] =  A[j]
                    j -= 1
                A[j+1] = tmp
            return A

    归并排序:O(n*log n)

      分治法思想。把所有的数看成长度为1的有序区间:[1],[2],[3],[5],[2],[3],再将相邻的区间合并成为最大长度为2的有序区间:[1,2],[3,5],[2,3],再合并成为最大长度为4的有序区间:[1,2,3,5],[2,3],再合并:[1,2,2,3,3,5]。 

    class MergeSort:
        def mergeSort(self, A, n):
            if n <= 1:
                return A
            half = n / 2
            left = self.mergeSort(A[:half], half)
            right = self.mergeSort(A[half:], n-half)
            
            result = []
            i = j = 0
            while i < len(left) and j < len(right):
                if left[i] < right[j]:
                    result.append(left[i])
                    i += 1
                else:
                    result.append(right[j])
                    j += 1
            result += left[i:]
            result += right[j:]
    
            return result

    快速排序:O(n*log n)

      从这些数中随意选一个数,小于这个数的放在它左边,大于它的放右边;再在这左右两边的一堆数重复使用这个方法,直到排序结束。

    class QuickSort:
        def quickSort(self, A, n=None):
            if not A:
                return []
            else:
                key = A[0]  # 固定每次选择最左边的数
                left = self.quickSort([n for n in A[1:] if n <= key])
                right = self.quickSort([n for n in A[1:] if n > key])
                return left + [key] + right

     堆排序:

      在这里我们借用wiki的定义来说明: 通常堆是通过一维数组来实现的,在阵列起始位置为0的情况中 

        (1)父节点i的左子节点在位置(2*i+1); 
        (2)父节点i的右子节点在位置(2*i+2); 
        (3)子节点i的父节点在位置floor((i-1)/2);

    # -*- coding:utf-8 -*-
    
    class HeapSort:
        def heapSort(self, A, n):
            # 创建大根堆
            for i in xrange(n/2 + 1, -1, -1): 
                self.max_heap_fix(A, i, n)
            # 堆排序
            for i in xrange(n-1, -1, -1):
                A[0], A[i] = A[i], A[0]
                self.max_heap_fix(A, 0, i)
            return A
    
        def max_heap_fix(self, A, i, n):
            """
            :param A: 大根堆、一维数组
            :param i: 预修复的子树根节点
            :param n: 大根堆总的元素数量
            """
            j = i * 2 + 1  # i的左子节点下标
            # 当i的左子节点存在时
            while j < n:
                # 当i的右子节点存在,且大于i的左子节点
                if j + 1 < n and A[j] < A[j+1]:
                    j += 1
                # 当i的左右子节点都小于i时,修复大根堆结束
                if A[j] < A[i]:
                    break
                # 当i的子节点大于i时,交换节点
                A[i], A[j] = A[j], A[i]
                i = j  # 将i移向于i交换的节点
                j = i * 2 + 1  # i的左子节点下标

    希尔排序:

       插入排序是希尔排序的一种特殊情况,当希尔排序的初始步长为1时,即为插入排序。

    class ShellSort:
        def shellSort(self, A, n):
            step = n / 2
            while step > 0:
                for i in xrange(step, n):
                    tmp = A[i]
                    while i >= step and tmp < A[i-step]:
                        A[i] = A[i-step]
                        i -= step
                    A[i] = tmp
                step = step / 2
            return A
  • 相关阅读:
    TI CC2541的整体目标
    TI CC2541的GPIO引脚设置.
    E2PROM与Flash的引脚图
    TI BLE CC2541的通讯协议.
    TI BLE CC2541的I2C主模式
    Charles如何抓取电脑上的请求的https数据包
    Charles如何抓取手机上的请求的https数据包
    谷歌浏览器chrome调试H5页面 如果添加cookie?
    Unity 好坑的Save Scene
    Unity 官网教程 -- Multiplayer Networking
  • 原文地址:https://www.cnblogs.com/wangchaowei/p/8275914.html
Copyright © 2011-2022 走看看