zoukankan      html  css  js  c++  java
  • 三、排序

    1. 冒泡排序

    • 思想:每次都是相邻元素进行比较,当后面的元素小于前面元素时,就进行交换位置 。
    • 时间复杂度:O(N^2)    空间复杂度:O(1)
    • 稳定性:稳定
    def bubble_sort_mod(array):  
        for i in range(len(array)): 
            is_sorted = True 
            for j in range(1, len(array) - i):
                if (array[j] < array[j - 1]):
                    array[j], array[j - 1] = array[j - 1], array[j]
                    is_sorted = False        
            if (is_sorted): break
        return array   
    

    2. 选择排序

    • 思想:是对冒泡排序的改进,每一轮仅进行一次交换,把最大值换到最后面即可。
    • 时间复杂度:O(N^2)     空间复杂度:O(1)
    • 稳定性:不稳定
    # 这里是每一轮换最大值,把最大值换到数组最后面去
    def selection_sort(nums):
        for i in range(len(nums)):
            pos_max = 0 
            for j in range(1, len(nums) - i):
                if nums[j] > nums[pos_max]:
                    pos_max = j 
            nums[len(nums)-i-1], nums[pos_max] = nums[pos_max], nums[len(nums)-i-1]
        return nums
    

    3.  插入排序

    • 思想:类似于打牌的时候人们插牌的方式,来一张新牌就把它与前面排好的牌进行比对,找到合适的插入位置。
    • 时间复杂度:O(N^2)    空间复杂度:O(1)
    • 稳定性:稳定
    def insert_sort(nums):
        for i in range(1, len(nums)):
            current_value = nums[i]
            position = i 
            while position > 0 and nums[position-1] > current_value:  # while 循环实现 
                nums[position] = nums[position-1]  # 移动操作仅一次赋值,是交换操作的三分之一,此时性能会好一些 
                position -= 1 
            nums[position] = current_value  # 插入 
        return nums
    

    4. 希尔排序

    • 思想:希尔排序就是再插入排序的基础上多了个gap而已。
    • 时间复杂度:O(N^1.3)       空间复杂度:O(1)
    • 稳定性:不稳定
    def shell_sort(nums):
        sublistcount = len(nums) // 2 
        while sublistcount > 0:
            for startposition in range(sublistcount):
                gapInsertionSort(nums, startposition, sublistcount)
            print("After increments of size", sublistcount, "The list is", nums)
            sublistcount = sublistcount // 2 
        return nums 
    
    def gapInsertionSort(nums, start, gap): #插入排序 
        for i in range(start+gap, len(nums), gap):
            currentvalue = nums[i]
            position = i 
        
            while position >= gap and nums[position-gap] > currentvalue:
                nums[position] = nums[position-gap]
                position -= gap 
            nums[position] = currentvalue 
    

    5. 计数排序

    • 思想:首先找到数组的最大值和最小值,根据这两个值制造一定长度的抽屉。其次要把数字一个个的放到抽屉里面,然后再按顺序拿出来。
    • 时间复杂度:O(N)     空间复杂度:O(K), K表示最大值与最小值之差
    • 稳定性:稳定
    def count_sort(items):
        mmax, mmin = max(items), min(items)
        nums = mmax - mmin + 1 
        counts = [0] * nums 
        for i in range(len(items)):
            counts[items[i]-mmin] = counts[items[i] - mmin] + 1 
        pos = 0 
        for i range(nums): # 只是从抽屉里把所有的数都拿出来,O(n)复杂度
            for j in range(counts[i]):
                items[pos] = i + mmin 
                pos += 1 
        return items 
    

    6. 归并排序

    • 思想:将数组持续分为两半,分别对两半运用双指针的办法进行归并排序。是一种递归的方法
    • 时间复杂度:O(N)   空间复杂度:O(1)
    • 稳定性:稳定
    # 更python的写法 
    def merge_sort(nums):
        if len(nums) <= 1: # base情况 也就是递归的结束条件
            return nums 
        # 分解问题,并递归调用
        middle = len(nums) // 2 
        left = merg_sort(nums[:middle])  #  左半部
        right = merg_sort(nums[middle:]) # 右半部
        
        # 合并左右半步,完成排序
        merged = []
        while left and right:
            if left[0] <= right[0]:
                merged.append(left.pop(0))
            else:
                merged.append(right.pop(0))
        merged.extend(right if right else left)
        return merged 
    

    7. 快速排序

    • 思想:依据一个“中值”数据项把数组分为两半:小于中值的一半和大于中值的一半。然后分别对两半进行快速排序。
    • 时间复杂度:O(NlgN)    空间复杂度:  首先就地快速排序使用的空间是O(1)的,也就是个常数级;而真正消耗空间的就是递归调用了,因为每次递归就要保持一些数据;
    • 稳定性:不稳定
    def quickSort(nums):
        quickSortHelper(nums, 0, len(nums)-1)
        
    def quickSortHelper(nums, first, last):
        if first < last:
            splitpoint = partition(nums, first, last) # 先找到中点 
            quickSortHelper(nums, first, splitpoint-1)
            quickSortHelper(nums, splitpoint+1, last)
    
    def partition(nums, first, last):
        pivotvalue = nums[first]
        leftmark = first + 1 
        rightmark = last
        done = False 
        while not done:
            while leftmark <= rightmark and nums[leftmark] <= pivotvalue:
                leftmark += 1 
            while leftmark <= rightmark and nums[rightmark] >= pivotvalue:
                rightmark -= 1
            if rightmark < leftmark:
                done = True 
            else:
                nums[leftmark], nums[rightmark] = nums[rightmark], nums[leftmark]
                
        nums[first], nums[rightmark] = nums[rightmark], nums[first]
        return rightmark 
    

      

  • 相关阅读:
    15 Action View 以及监听 的使用
    15 ActionProvider代码例子
    15 ActionBar 总结
    15 Actionbar的显示和隐藏
    14 fragment传值
    14 fragment 创建
    14 Fragment 注意点
    14 Fragment 碎片总结
    GSON TypeToken 解决泛型问题
    Intent传递对象——Serializable和Parcelable区别
  • 原文地址:https://www.cnblogs.com/carlber/p/14175581.html
Copyright © 2011-2022 走看看