zoukankan      html  css  js  c++  java
  • 选择排序(直接选择排序、堆排序)

    选择排序的基本方法:
    每次都从待排序对象中选出排序码最大或最小的对象,依次排列,一共进行n-1次即可将n个对象排序完成。
    选择排序的实施方案:
    1. 直接选择排序
    2. 堆排序

    一、直接选择排序
    1. 算法代码:

    /**
    * 直接选择排序
    **/
    func SelectSort(data []int) {
    	for i := 0; i < len(data)-1; i++ {
    		minIndex := i //保存最小值的索引
    		for j := i + 1; j < len(data); j++ {
    			if data[j] < data[minIndex] {
    				minIndex = j
    			}
    		}
    		if minIndex != i {
    			data[minIndex], data[i] = data[i], data[minIndex]
    		}
    	}
    }
    

    2. 时间复杂度:O(n*n)
    缺陷:每次都要从n-i+1个记录中选一个排序码最小的对象,从而需要进行n-i次比较,当n很大时,其效率很低。
    3. 稳定性:不稳定

    二、堆排序
    关于堆的介绍与实现可以先查看我的另一篇博文:https://www.cnblogs.com/wujuntian/p/12286502.html
    1. 算法描述:
    使用最小堆或最大堆来选出待排序对象的最小或最大排序码对象。
    2. 算法代码:
    可以使用最小堆或者最大堆实现,其中使用最大堆算法的空间复杂度更优,因为只需在原来数组上对数据位置进行调整即可,而使用最小堆排序的话还需要使用一个额外的数组来存储排序结果。所以这里只给出使用最大堆的算法。

    /**
    * 堆排序(使用最大堆)
    **/
    func HeapSort(data []int) {
    	count := len(data)                      //最大堆数据个数
    	for i := (count - 2) / 2; i >= 0; i-- { //从拥有孩子节点的最后一个父节点开始,向下调整,初始化最大堆
    		shiftDown(data, i, count-1)
    	}
    	for count > 1 {
    		data[0], data[count-1] = data[count-1], data[0] //将堆顶元素与最后一个元素交换位置
    		count--                                         //最大堆数据个数减少
    		shiftDown(data, 0, count-1)                     //向下调整最大堆
    	}
    }
    
    /**
    * 向下调整最大堆
    **/
    func shiftDown(data []int, start, end int) {
    	i, j := start, start*2+1 //j为i的左孩子
    	temp := data[i]
    	for j <= end {
    		if j+1 <= end && data[j+1] > data[j] { //取左右孩子的最大值
    			j++
    		}
    		if data[j] > temp { //孩子比父节点大,交换数值,继续向下调整
    			data[i] = data[j]
    			i, j = j, j*2+1
    		} else {
    			break
    		}
    	}
    	data[i] = temp
    }
    

    3. 时间复杂度:O(nlogn)
    直接选择排序进行了很多重复的比较,而堆则相当于保存了比较结果,避免太多重复比较,所以比较次数较少,但是由于建立初始堆所需的比较次数较多,所以堆排序对记录数较少的序列并不值得提倡,但对于数目较大的序列来说还是很有效的。
    4. 空间复杂度:O(1)
    5. 稳定性:不稳定

  • 相关阅读:
    Opencv中cvCopy()和cvCloneImage()的区别(转)
    什么是DC?
    UpdateDate()函数的作用
    宏定义函数指针类型【转】
    将openCV中的IplImage格式的图片显示到Picture控件上
    C程序调用shell脚本共有三种方法
    memset ,memcpy ,memmove,strcpy 的根本区别 与实现
    sizeof strlen length()
    itoa 实现
    string 与 char * 转换
  • 原文地址:https://www.cnblogs.com/wujuntian/p/12303192.html
Copyright © 2011-2022 走看看