选择排序&&堆排序

1.选择排序:

  介绍:选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

  步骤:假设数组array长度为N即有数组内有N个数据未排序数据

  1.第一趟遍历将这N个数据中最小的数据和array[0]交换。

  2.第二趟则遍历N-1个数据,将这N-1个数据中最小的和array[1]交换(第二趟中的数组是从原数组中的array[1]开始即排除第一趟中最小的数据再进行交换)。

  ...

  程序实现:

方法1:每趟选择最小数据进行交换

 void SelectSort(int* _array, size_t _arraySize)
{
assert(_array&&_arraySize);
for (size_t i = ;i < _arraySize;++i)
{
int MinIndex = i;//记录首位置下标
for (size_t j = i + ;j < _arraySize;++j)
{
if (_array[MinIndex] > _array[j])//比较首位置之后的各个元素并将最小数据的下标赋给MinIndex
MinIndex = j;
}
//if (MinIndex != i)//防止首元素即最小时进行交换,减少不必要开销
swap(_array[MinIndex], _array[i]);
}
return;
}

方法2:与方法一类似,进行了优化,每趟将最小数据置首,将最大元素置尾

 void SelectSort_optimize(int* _array, int _arraySize)
{
assert(_array&&_arraySize); int left = ;
int right = _arraySize - ;
for (;left <= right;++left,--right)//每一趟找到最大值和最小值减少循环次数
{
int MinIndex = left;
int MaxIndex = right;
for (int index = left;index <= right;++index)//此时数组为闭区间,与未优化时存在差异
{
if (_array[MinIndex] > _array[index])
MinIndex = index;
if (_array[MaxIndex] < _array[index])
MaxIndex = index;
}
if (left != MinIndex)
{
swap(_array[left], _array[MinIndex]);
if (left == MaxIndex)//避免如果最大值为_array[left]时,将被上一步操作移到_array[MinIndex]后出错
MaxIndex = MinIndex;//将MaxIndex更新
}
if (right != MaxIndex)
swap(_array[right], _array[MaxIndex]);
}
return;
}

效率分析:

  算法稳定性:不稳定

  时间复杂度:O(n^2)

  空间复杂度:O(1)

2.堆排序
  介绍:堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大堆和小堆,是完全二叉树。升序排序时使用大堆,降序排序时使用小堆。

步骤:对数组_array进行升序排序,假设数组array长度为N即有数组内有N个数据未排序数据

    1:将_array中的N个数据构成大堆后,此时最大值即为_array[0],然后将_array[0]与_array[N-1]交换。

   2:除_array[N-1]外,其余数据继续建立大堆后,此时最大值仍为_array[0],然后将_array[0]与_array[N-2]交换。

   ...

  根据下面网址演示可以清楚理解堆排序的过程

http://www.tyut.edu.cn/kecheng1/site01/suanfayanshi/heap_sort.asp

 程序实现:

 void AdjustDown(int* _arr,size_t ParIndex,int _arrSize)//从父节点开始向下调整
{
size_t ChildIndex = ParIndex * + ;//找出父节点的左子树下标 while (ChildIndex < _arrSize)
{
if ((_arr[ChildIndex] < _arr[ChildIndex + ]) && ((ChildIndex + ) < _arrSize))//找出父节点的左右子树中的较大值的下标
ChildIndex++;
if (_arr[ParIndex] < _arr[ChildIndex])
{
swap(_arr[ParIndex], _arr[ChildIndex]);//如果父节点数据小于子节点数据则交换
ParIndex = ChildIndex; //继续调整交换后的子树,保证堆中任意子树均为大堆
ChildIndex = ParIndex * + ;
}
else//如果_arr[ParIndex] > _arr[ChildIndex]则说明其已经为大堆且子树也为大堆,跳出循环
break;
}
}
void HeapSort(int* _array, int _arraySize)
{
assert(_array&&_arraySize > );
//建堆
for (int i = _arraySize / - ;i >= ;--i)//从最后一个非叶子节点开始向下调整直到根节点调整完
AdjustDown(_array, i, _arraySize); for (int j = _arraySize - ;j > ;--j)
{
swap(_array[], _array[j]);
AdjustDown(_array, ,j);
}
return;
}

下面是当数组为{3,12,24,2,6}时的排序过程

效率分析:

  算法稳定性:不稳定

  时间复杂度:O(n^lg n)

  空间复杂度:O(1)

排序 选择排序&&堆排序的更多相关文章

  1. 跳跃空间(链表)排序 选择排序(selection sort),插入排序(insertion sort)

    跳跃空间(链表)排序 选择排序(selection sort),插入排序(insertion sort) 选择排序(selection sort) 算法原理:有一筐苹果,先挑出最大的一个放在最后,然后 ...

  2. 内部排序->选择排序->堆排序

    文字描述 堆排序中,待排序数据同样可以用完全二叉树表示, 完全二叉树的所有非终端结点的值均不大于(或小于)其左.右孩子结点的值.由此,若序列{k1, k2, …, kn}是堆,则堆顶元素(或完全二叉树 ...

  3. java实现 排序算法(鸡尾酒排序&选择排序&插入排序&二分插入排序)

    1.鸡尾酒排序算法 源程序代码: package com.SuanFa; public class Cocktial {    public static void main(String[] arg ...

  4. JAVA排序--[选择排序]

    package com.array; public class Sort_Select { /** * 项目名称:选择排序 ; * 项目要求:用JAVA对数组进行排序,并运用选择排序算法; * 作者: ...

  5. C-冒泡排序,选择排序,数组

    ——构造类型 ->数组      ->一维数组      ->相同类型的一组数据      ->类型修饰符--数组名—[数组的元素个数(必须是整型表达式或者是整型常量,不能是变 ...

  6. 内部排序->选择排序->树形选择排序

    文字描述 树形选择排序又称锦标赛排序; 比如,在8个运动员中决出前3名至多需要11场比赛, 而不是7+6+5=18场比赛(它的前提是甲胜乙,乙胜丙,则甲必能胜丙) 首先对n个记录的关键字进行两两比较, ...

  7. 内部排序->选择排序->简单选择排序

    文字描述 简单排序的基本思想是:每一趟在n-i+1(i=1,2,…,n)个记录中选取关键字最小的记录作为有序列表中的第i个记录. 示意图 略 算法分析 简单排序算法中,所需进行记录移动的操作次数较少, ...

  8. 排序——选择排序(java描述)

    百度百科的描述如下:选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元 ...

  9. [javaSE] 数组(排序-选择排序)

    两层嵌套循环,外层循环控制次数,内层循环进行比较 for(int x=0;x<arr.length;x++){ for(int y=0;y<arr.length;y++){ if(arr[ ...

随机推荐

  1. [ CodeVS冲杯之路 ] P1053

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/1053/ 直接扫一遍串,把字母对应的 ascii 码直接做数组下标,交给数组统计 最后查询一遍数组的 'a'-'z' , ...

  2. Win2D 官方文章系列翻译 - 幕后绘制

    本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-offscreen-drawing/ 应用有时需要将图形绘制到并不立即显示的目标上.此类绘制动作被称作“幕后绘 ...

  3. 实验室中搭建Spark集群和PyCUDA开发环境

    1.安装CUDA 1.1安装前工作 1.1.1选取实验器材 实验中的每台计算机均装有双系统.选择其中一台计算机作为master节点,配置有GeForce GTX 650显卡,拥有384个CUDA核心. ...

  4. Class attributes

    In order to print Card objects in a way that people can easily read, we need a mapping from the inte ...

  5. 学习记录 Eclipse常用快捷键及其演练

    Eclipse中10个最有用的快捷键组合 1. ctrl+shift+r:打开资源 这可能是所有快捷键组合中最省时间的了.这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask ...

  6. 洛谷P2728 纺车的轮子 Spinning Wheels

     P2728 纺车的轮子 Spinning Wheels 29通过 66提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交  讨论  题解 最新讨论 暂时没有讨论 题目背景 一架纺车 ...

  7. ASP.NET运行机制原理 ---浏览器与IIS的交互过程 自己学习 网上查了下别人写的总结的很好 就转过来了 和自己写的还好里嘻嘻

    一.浏览器和服务器的交互原理 (一).浏览器和服务器交互的简单描述: 1.通俗描述:我们平时通过浏览器来访问网站,其实就相当于你通过浏览器去访问一台电脑上访问文件一样,只不过浏览器的访问请求是由被访问 ...

  8. md5的一些用法

    package md5; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /* * ...

  9. 使用ffmpeg快速生成视频截图

    1 ffmpeg -i input.mkv -ss 00:10:00 -f image2 output.jpg 但是这个命令会花费相当长的时间. 对一个清晰的或者较大的视频文件进行操作, 会花费半分钟 ...

  10. [微信开发利器]微信内移动前端开发抓包调试工具fiddler使用教程

    [微信开发利器]微信内移动前端开发抓包调试工具fiddler使用教程   在朋友圈看到一款疯转的H5小游戏,想要copy,什么?只能在微信里打开?小样,图样图森破,限制了oauth.微信浏览器内打开, ...