简单选择排序与堆排序
来源:互联网 发布:翻转课堂软件 编辑:程序博客网 时间:2024/04/28 07:54
选择排序的基本运算都是在n个元素组成的序列中,选择一个关键字最大或最小的元素输出,然后再从剩余的n-1个元素中选择一个关键字最大或最小的元素输出,以此类推,直到排序结束。
以递增排序为例,简单选择排序过程如下:1第一次在数组中查找最小值a[i],然后将a[i]和a[0]交换位置。
2从a[1]开始,同样从a[1]开始往后找到最小值a[j],然后与a[1]交换位置,依次类推。
废话不多说,直接贴代码
//**************5简单选择排序************************//比冒泡法交换的次数少,比较多,交换少void SelectSort(int a[],int len){int i,j,min,temp;for(i=0;i<len-1;i++){min=i;for(j=i+1;j<len;j++)if(a[j]<a[min])min=j;temp=a[i];a[i]=a[min];a[min]=temp;}}
简单选择排序 时间复杂度O(n^2)
稳定性分析:选择排序是给每个位置选择当前元素最小(或最大)的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个 元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么 交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9, 我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序是一个不稳定的排序算法。
简单选择排序的时间主要浪费在对于n个元素(乱序)如何----在小于O(n)时间内查找最大值或最小值
改进:堆排序
堆是一棵完全二叉树,其中任一非叶子节点的关键字均大于(或小于)等于其孩子节点的关键字。分为最大堆和最小堆
用最大堆进行升序排序:先构造初始最大堆,由于最大堆的第一个关键字就是最大值,直接将第一个关键字和最后一个关键字交换(是不是和简单选择排序很相似),然后再调整其余关键字,使其重新构成最大堆,然后再将第一个关键字与当前最大堆的最后一个关键字交换,依次类推,直到排序完成。
简而言之就是: 构造初始堆---->取堆顶------>调整剩余堆------>取剩余堆顶------->.........-------->空堆end
构造初始堆的过程描述如下:
废话不多说,直接上代码:
//*****************6堆排序*******************************//升序排序构造大顶堆,每次把最大元素(根)放在数组最后一个位置//对于剩余元素重新构造二叉堆-----以数组形式存储堆 (完全二叉树)void HeapAdjust(int a[], int i, int size) {//调整堆(大小为size--a[0~size])的第i个节点使之为大顶堆 size=len-1;节点编号0,1,...size.int lchild = 2*i+1;//i的左孩子节点序号int rchild = 2*i+2;//i的右孩子节点序号int max=i;int temp;if(i<=size/2)//如果i是叶节点就不用进行调整{if(lchild<=size && a[lchild]>a[max])max=lchild;if(rchild<=size && a[rchild]>a[max])max=rchild;if(max!=i){temp=a[i];a[i]=a[max];a[max]=temp;//避免调整之后以man为父节点的子树不是大顶堆HeapAdjust(a,max,size); }}}void HeapSort(int a[],int size){//HeapSort(a,9);size=n-1;不是元素个数int i,temp;for(i=size/2;i>=0;i--)//建立初始堆 非叶子节点最大序号值为size/2 HeapAdjust(a,i,size);for(i=size;i>=0;i--){temp=a[0]; //交换堆顶和最后一个元素a[0]=a[i];a[i]=temp;//BuildHeap(a[],i-1);//将余下元素重新建立为大顶堆HeapAdjust(a,0,i-1);//重新调整堆顶节点成为大顶堆}}
由于堆是完全二叉树,其实还是用数组来描述堆。。。。。
下面对代码进行解释:
HeapSort第一个for循环就是建立堆的过程,从第一个非叶子节点开始进行调整堆(HeapAdjust)最后一个个非叶子节点可能是size/2,可有可能是size/2-1,至于为什么从编号为size/2开始,是为了保证最大可能性,进一步的确定是不是叶子节点可在HeapSort中的if(lchild<=size)等中进行判断。
HeapSort第二个for循环就是取堆顶,调整堆的过程。
下面分析时间复杂度(参考算法导论)
分析调整堆的时间复杂度
重调堆,时间复杂度为T(lgn)
堆排序的时间复杂度T(nlgn) 无论最好最坏都是一样的
- 简单选择排序与堆排序
- 简单选择排序与堆排序
- 选择排序---简单选择排序 堆排序
- 选择排序:简单选择排序、堆排序
- 简单选择排序-->堆排序
- 选择排序与堆排序
- 简单选择排序与堆排序的比较
- 内部排序之选择排序:简单选择排序,堆排序
- 选择排序之简单选择排序与堆排序C/C++
- 简单选择排序和堆排序
- (五)选择排序:简单选择排序,堆排序
- 深入浅出选择类排序算法(简单选择排序,堆排序)
- 三 选择排序(简单选择排序和堆排序)
- 深入浅出选择类排序算法(简单选择排序,堆排序)
- 选择类排序-堆排序 简单选择排序
- 选择排序之--简单选择排序,堆排序
- 选择排序(简单选择排序 and 堆排序)
- 简单选择排序,树形选择排序,堆排序详解
- 黑马程序员——用正则表达式校验QQ号码
- mac下node.js 安装express后报express command not found
- 说说JSON和JSONP,也许你会豁然开朗
- Ubuntu 修改终端显示的主机名和用户名
- 认识SCI、EI、ISTP、SSCI、INSPEC、SCIE、IEEE、CSCD、CSSCI
- 简单选择排序与堆排序
- Cocoa Touch事件处理流程--响应者链
- cmake tutorial
- android telephony 工作流程(一)--UICC概述及SIM卡文件系统
- 12-Roman to Integer-字符串相关-HashMap
- java实现顺序栈
- ONOS预热篇之ONOS简介(一)
- 建立dblink(database link)
- PDF转换为PPT详细的方法