js 数组按照特定值筛选排序_程序员面试常问算法:选择类排序法

一、算法思想

选择排序的基本思想是:第一次从待排序的记录中选出最小(最大)的一个记录,存放在序列的起始位置,然后再从剩余的未排序记录中寻找到最小(大)元素,然后放到已排序的序列的末尾,以此类推。这里主要简单展开介绍简单选择排序、树形排序和堆排序。

2c90a24012a64d6f325b4589b9590cde.png

二、简单选择排序

原理:

1、从待排序的记录中逐个比较第一个与其后记录的大小,选出最小(最大)的一个记录,与第一个位置的记录互换。

2、然后再从剩余的未排序记录中寻找到最小(大)元素,即重复1过程。

算法推演:

简单选择排序类似于冒泡排序(冒泡排序中相邻两个记录可以交换),直观简单。

简单选择排序是待排序列表的第一个值与后面的值比较,选择这一趟比较的最大值或最小值。

例如,排序列表{10,78,5,80,3}

786fa54444b68a5f066609b0f8cf1b56.png

简单选择排序简单示意图

进一步的算法执行过程

9aa741306db79bf39020f69327ea37d2.png

算法执行示意明细

python3代码实现

def selection_sort(sort_list):    for i in range(len(sort_list)-1):        #起始元素位置索引        min_index = i        print("--记录开始比较位置"+str(i)+"值为:"+str(sort_list[i]))        #逐步两两比较        for j in range(i + 1, len(sort_list)):            print("----记录"+str(sort_list[j])+"与"+str(sort_list[min_index])+"比较大小")            if sort_list[j] < sort_list[min_index]:                print("--------最小值发生改变,"+str(sort_list[j])+"为临时最小值")                min_index = j        if i!=min_index:            print("----最小值索引发生改变,索引位置互换,即"+str(sort_list[i])+"与"+str(sort_list[min_index])+"互换")            sort_list[min_index], sort_list[i] = sort_list[i], sort_list[min_index]        print("--第"+str(i+1)+"趟排序的结果:",sort_list)sort_list=[10, 78 , 5,80,3]print("排序前:",sort_list)selection_sort(sort_list)print("排序后:",sort_list)

三、树形选择排序

原理:首先对 n 个记录的关键字进行两两比较,然后在其中 不大于 n/2 的整数个较小者之间再进行两两比较,直到选出最小关键字的记录为止。可以用一棵有 n 个叶子结点的完全二叉树表示。

例如,排序列表【10, 78, 5, 80, 3,12】

8ca0aa9ee17c444e1b5b7300fb15ebe6.png

第1轮两两比较结果,取出最小值3

b64a7ab8e31c8db4de5109e5475e92ec.png

第2轮两两比较结果,取出最小值5,原取值的节点值为None

22aa304cffaa9ec957eab60aa05ad3b7.png

第3轮两两比较结果,取出最小值10,原取值的节点值为None

1f0bec91ffc43ee02916d0780d4ac874.png

第4轮两两比较结果,取出最小值12,原取值的节点值为None

81e6d9095de5d6575cf46d0c01ccbea6.png

第5轮两两比较结果,取出最小值78,原取值的节点值为None

第6轮,剩余一个节点,直接取出。

最后取出排序结果:

【3, 5, 10, 12, 78,80】

树形选择排序算法缺点有:

1、与None的比较多余

2、辅助空间使用多(以空间换时间)

四、构建堆与堆排序

1、构建堆

一般我们使用数组来存放最大堆,通过二叉树进行分析的。

它们满足的性质为:

二叉树中所有的父节点的值都不大于/不小于其子节点;根节点的值必定是所有节点中最小/最大的。

数组的保存形式为:

父亲节点:i

左孩子节点:2∗i2∗i

右孩子节点:2∗i+1

二维数组初始堆

例如,排序列表【10, 78, 5, 80, 3,12】

c6bd827033bf3fa04416ecdb9e10e93f.png

开始构建堆一般从二叉树的倒数第一个叶子节点开始,n//2(python语法),n为二叉树的节点数量,在本例中是从5开始,节点往上开始构建。

1c27b7b549c911a00fdf5e016a0751ee.png

构建完成的二叉树(小根堆)如下图所示:

cef111b29e2f21adee82af84a951b4c5.png

2、堆排序

堆排序基本思路为:

  1. 构建最小堆(最大堆)
  2. 取出最小值(最大值)、将剩余n-1个记录重新构建新堆
  3. 重复2.过程,进行n-1次筛选

经过n-1次筛选结果如下图:

bc729d8a01c6148b4fa3070f22578510.png

3、堆构建和堆排序的python实现

def heapify(arr, n, idx):     min = idx    left = 2 * idx + 1    right = 2 * idx + 2    #如果父节点值大于LEFT节点值,则记录LEFT节点为最小值,    if left < n and arr[idx] > arr[left]:         min = left     #如果最小值大于RIGHT节点值,则记录RIGHT节点为最小值    if right < n and arr[min] > arr[right]:         min = right     #比较索引是否改变    if min != idx:         # 交换        arr[idx],arr[min] = arr[min],arr[idx]        #递归构建堆        heapify(arr, n, min)   def heapSort(arr):     n = len(arr)     # 构建最小值堆. 正常为n-1开始倒序,又索引从零0开始,则为n-1-1开始构建    for i in range((n-1-1)//2, -1, -1):         heapify(arr, n, i)     print("构建后:",arr)    # 取出最小值,放在数组尾    for i in range(n-1, 0, -1):         #交换        arr[i], arr[0] = arr[0], arr[i]        #重新构建堆,因为根节点已经是最小值了,数组arr中索引位置i的值不再参与运算(传递的i为数组的长度,每次循环都-1)        heapify(arr, i, 0)   arr = [ 10, 78, 5, 80, 3,12] print ("排序前:",arr) heapSort(arr) print ("排序后:",arr) 

代码亲测可行!

水平有限,若有不足,还望批评指正!

b27ef6d43c7d6499811512254a7512c5.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值