八大排序--整理

查找

  1. 既希望较快的查找又便于线性表动态变化的查找方法是哈希法查找。二叉排序树查找,最优二叉树查找,键树查找,哈希法查找是动态查找。分块、顺序、折半、索引顺序查找均为静态。分块法应该是将整个线性表分成若干块进行保存,若动态变化则可以添加在表的尾部(非顺序结构),时间复杂度是O(1),查找复杂度为O(n);若每个表内部为顺序结构,则可用二分法将查找时间复杂度降至O(logn),但同时动态变化复杂度则变成O(n);顺序法是挨个查找,这种方法最容易实现,不过查找时间复杂度都是O(n),动态变化时可将保存值放入线性表尾部,则时间复杂度为O(1);二分法是基于顺序表的一种查找方式,时间复杂度为O(logn);通过哈希函数将值转化成存放该值的目标地址,O(1)
  2. 二叉树的平均查找长度为O(log2n)——O(n).二叉排序树的查找效率与二叉树的高度有关,高度越低,查找效率越高。二叉树的查找成功的平均查找长度ASL不超过二叉树的高度。二叉树的高度与二叉树的形态有关,n个节点的完全二叉树高度最小,高度为[log2n]+1,n个节点的单只二叉树的高度最大,高度为n,此时查找成功的ASL为最大(n+1)/2,因此二叉树的高度范围为[log2n]+1——n.
  3. 链式存储不能随机访问,必须是顺序存储

https://cuijiahua.com/blog/2018/01/algorithm_6.html

一、冒泡排序(交换排序)

二、直接插入排序(插入排序)

三:希尔排序(插入排序)

四:快速排序(交换排序)

五:简单选择排序(选择排序)

六:堆排序(选择排序)

七:归并排序

八:基数排序(非比较型整数排序算法)


ç¨åºåååï¼å«å¤§æåºç®æ³

快排:数据越随机,效果越好

冒泡:数据越有序,效果越好

一、冒泡排序(交换排序)

思想:重复的走访要排序的数列,一次比较两个元素。如果顺序错误就交换,直到没有需要交换的元素。

优化:加入标志性变量exchange(吧),用于标志某一趟排序过程是否有数据交换。

code:

def bubble_sort(list):
    for i in range(len(list)-1):
        b = False
        print('第%d趟排序:' % (i + 1))
        for j in range(len(list)-1):
            if list[j] > list[j+1]:
                a = list[j]
                list[j] = list[j+1]
                list[j+1] = a
                b = True
            print(list)
        if not b:
            break
    return list

my_list = [12,1,5,23,8,2,8,3,89,4,5,7,23,7]
print(bubble_sort(my_list))

运行结果:

 

二、直接插入排序(插入排序)

思想:每一趟将一个待排序的数字插入到有序序列中,直到全部插入完成。

优化:在有序序列中插入一个数,可用二分查找,减少元素比较次数提高效率。

code:

def insert_sort(list):
    if len(list) == 0:
        return []
    sorted_list = list

    for i in range(1, len(sorted_list)):
        temp = sorted_list[i]
        j = i - 1
        while j >= 0 and temp < sorted_list[j]:
            sorted_list[j+1] = sorted_list[j]
            j = j-1
        sorted_list[j + 1] = temp
    return sorted_list
        
my_list = [3,2,5,9,8,6]
print(insert_sort(my_list))

运行结果

优化:

def binary_search(list, end, item):
    low = 0
    high = end - 1

    while low <= high:
        mid = int((low + high)/2)
        guess = list[mid]
        if guess <= item:
            low = mid + 1
        else:
            high = mid-1
    return low if low < end else -1

def insert_sort(list):
    if len(list) == 0:
        return []
    sorted_list = list
    for i in range(1, len(list)):
        j =i-1
        temp = sorted_list[i]
        index = binary_search(list, i, temp)
        while index != -1 and j >= index:
            sorted_list[j+1] = sorted_list[j]
            j -= 1
        sorted_list[j+1] = temp
    
    return sorted_list
        
my_list = [3,2,5,9,8,6]
print(insert_sort(my_list))

三:希尔排序(插入排序)

思想:对要排序的序列,先以步长5(步长选择自由,这里只是举例说明)对序列按行进行分割,然后按列进行排序;对得到的序列以步长3分割,按列排序‘最后步长为1排序。

code:

def shell_sort(arr):
    if len(arr) <= 1:
        return arr
    length = len(arr)
    gap = length // 2
    while gap > 0:
        for i in range(gap, length):
            j = i - gap
            temp = arr[i]
            while j >= 0 and arr[j] > temp:
                arr[j + gap] = arr[j]
                j -= gap
            arr[j+gap] = temp
        gap //= 2
    return arr

    
my_list = [3,2,5,9,8,6]
print(shell_sort(my_list))

四:快速排序(交换排序)

思想:分而治之。通过排序将序列分割为两部分,左边都是比基线条件小的数,右边都是比它大的数;然后再按照这个方法对分割后的两个序列排序,使用递归进行快速排序。

code:

def quicksort(arr):
    if len(arr) < 1:
        return arr
    else:
        median = arr[0]
        less = [i for i in arr[1:] if i <= median]
        greater = [i for i in arr[1:] if i > median]
        return quicksort(less) + [median] + quicksort(greater)

my_arr = [3,2,6,8,4,3,1,2,0]

print(quicksort(my_arr))

五:简单选择排序(选择排序)

思想:每趟从待排序的序列中选出最小的数,顺序放在以排序的序列末尾,直到全部排序为止。

code:

def findsmallest(arr):
    smallest = arr[0]
    smallest_index = 0
    for i in range(len(arr)):
        if smallest > arr[i]:
            smallest = arr[i]
            smallest_index = i
    return smallest_index

def selectionsort(arr):
    newarr = []
    for i in range(len(arr)):
        smallest = findsmallest(arr)
        newarr.append(arr.pop(smallest))
    return newarr

print(selectionsort([2,5,7,8,6]))

六:堆排序(选择排序)

思想:堆排序是利用堆的性质进行的一种选择排序。

当想得到一个序列中第k个最小的元素之前的部分排序序列,最好采用堆排序。

# -*- coding: utf-8 -*-
"""
Created on Wed Feb 20 18:13:01 2019

@author: AAA
"""


def HeadSort(input_list):
	'''
	函数说明:堆排序(升序)
	Author:
		www.cuijiahua.com
	Parameters:
		input_list - 待排序列表
	Returns:
		sorted_list - 升序排序好的列表
	'''
	def HeadAdjust(input_list, parent, length):
		'''
		函数说明:堆调整,调整为最大堆
		Author:
			www.cuijiahua.com
		Parameters:
			input_list - 待排序列表
			parent - 堆的父结点
			length - 数组长度
		Returns:
			无
		'''	
		temp = input_list[parent]
		child = 2 * parent + 1

		while child < length:
			if child + 1 < length and input_list[child] < input_list[child+1]:
				child += 1
			if temp >= input_list[child]:
				break

			input_list[parent] = input_list[child]

			parent = child
			child = 2 * parent + 1
		input_list[parent] = temp

	if len(input_list) == 0:
		return []
	sorted_list = input_list
	length = len(sorted_list)

	for i in range(0, length // 2)[::-1]:
		HeadAdjust(sorted_list, i, length)

	for j in range(1, length)[::-1]:
		temp = sorted_list[j]
		sorted_list[j] = sorted_list[0]
		sorted_list[0] = temp

		HeadAdjust(sorted_list, 0, j)
		print('第%d趟排序:' % (length - j), end = '')
		print(sorted_list)

	return sorted_list

if __name__ == '__main__':
	input_list = [6, 4, 8, 7, 9, 2, 3, 1]
	print('排序前:', input_list)
	sorted_list = HeadSort(input_list)
	print('排序后:', sorted_list)

七:归并排序

思想:分而治之

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

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

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

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

# -*- coding:utf-8 -*-
def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr)//2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return merge(left, right)

def merge(a, b):
    c = []
    i = 0
    j = 0
    while i < len(a) and j < len(b):
        if a[i] < b[j]:
            c.append(a[i])
            i += 1
        else:
            c.append(b[j])
            j += 1
    if i == len(a):
        for ii in b[j:]:
            c.append(ii)
    elif j == len(b):
        for jj in a[i:]:
            c.append(jj)
    return c

if __name__ == '__main__':
    merge_sort([2,4,6,2,1,123,57])

八:基数排序(非比较型整数排序算法)

参考:https://blog.csdn.net/weixin_40924580/article/details/83999964

# -*- coding: utf-8 -*-
"""
Created on Thu Feb 21 13:37:30 2019

@author: AAA
"""

def RadixSort(input_list):
    i = 0                                             #初始为个位排序
    n = 1                                           #最小的位数置为1(包含0)
    max_num = max(input_list)                       #得到带排序数组中最大数
    while max_num > 10**n:              #得到最大数是几位数
        n += 1
    while i < n:
        bucket = {}                             #用字典构建桶
        for x in range(10):
            bucket.setdefault(x, [])    #将每个桶置空
        for x in input_list:                               #对每一位进行排序
            radix =int((x / (10**i)) % 10)   #得到每位的基数
            bucket[radix].append(x) #将对应的数组元素加入到相应位基数的桶中
        j = 0
        for k in range(10):
            if len(bucket[k]) != 0:       #若桶不为空
                for y in bucket[k]:         #将该桶中每个元素
                    input_list[j] = y                       #放回到数组中
                    j += 1
        i += 1
    return input_list


if __name__ == '__main__':
	input_list = [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
	print('排序前:', input_list)
	sorted_list = RadixSort(input_list)
	print('排序后:', sorted_list)

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值