zoukankan      html  css  js  c++  java
  • 排序 选择排序&&堆排序

    选择排序&&堆排序

    1.选择排序:  

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

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

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

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

      ...

     

      程序实现:

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

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

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

     1 void SelectSort_optimize(int* _array, int _arraySize)
     2 {
     3     assert(_array&&_arraySize);
     4 
     5     int left = 0;
     6     int right = _arraySize - 1;
     7     for (;left <= right;++left,--right)//每一趟找到最大值和最小值减少循环次数
     8     {
     9         int MinIndex = left;
    10         int MaxIndex = right;
    11         for (int index = left;index <= right;++index)//此时数组为闭区间,与未优化时存在差异
    12         {
    13             if (_array[MinIndex] > _array[index])
    14                 MinIndex = index;
    15             if (_array[MaxIndex] < _array[index])
    16                 MaxIndex = index;
    17         }
    18         if (left != MinIndex)
    19         {
    20             swap(_array[left], _array[MinIndex]);
    21             if (left == MaxIndex)//避免如果最大值为_array[left]时,将被上一步操作移到_array[MinIndex]后出错
    22                 MaxIndex = MinIndex;//将MaxIndex更新
    23         }
    24         if (right != MaxIndex)
    25             swap(_array[right], _array[MaxIndex]);
    26     }
    27     return;
    28 }

    效率分析:

      算法稳定性:不稳定

      时间复杂度: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

     程序实现:

     1 void AdjustDown(int* _arr,size_t ParIndex,int _arrSize)//从父节点开始向下调整
     2 {
     3     size_t ChildIndex = ParIndex * 2 + 1;//找出父节点的左子树下标
     4 
     5     while (ChildIndex < _arrSize)
     6     {
     7         if ((_arr[ChildIndex] < _arr[ChildIndex + 1]) && ((ChildIndex + 1) < _arrSize))//找出父节点的左右子树中的较大值的下标
     8             ChildIndex++;
     9         if (_arr[ParIndex] < _arr[ChildIndex])
    10         {
    11             swap(_arr[ParIndex], _arr[ChildIndex]);//如果父节点数据小于子节点数据则交换
    12             ParIndex = ChildIndex;    //继续调整交换后的子树,保证堆中任意子树均为大堆
    13             ChildIndex = ParIndex * 2 + 1;
    14         }
    15         else//如果_arr[ParIndex] > _arr[ChildIndex]则说明其已经为大堆且子树也为大堆,跳出循环
    16             break;
    17     }
    18 }
    19 void HeapSort(int* _array, int _arraySize)
    20 {
    21     assert(_array&&_arraySize > 0);
    22     //建堆
    23     for (int i = _arraySize / 2 - 1;i >= 0;--i)//从最后一个非叶子节点开始向下调整直到根节点调整完
    24         AdjustDown(_array, i, _arraySize);
    25 
    26     for (int j = _arraySize - 1;j > 0;--j)
    27     {
    28         swap(_array[0], _array[j]);
    29         AdjustDown(_array, 0,j);
    30     }
    31     return;
    32 }

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

     

    效率分析:

      算法稳定性:不稳定

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

      空间复杂度:O(1)

     

  • 相关阅读:
    八款常用的 Python GUI 开发框架推荐
    scrapy + mogoDB 网站爬虫
    tkinter界面卡死的解决办法
    通过核心API启动单个或多个scrapy爬虫
    爬虫怎样绕过验证码?
    Python爬虫入门教程 33-100 电影评论数据抓取 scrapy
    Python开发 之 Websocket 的使用示例
    StringBuffer详解
    其实python正则表达式就这样简单明了
    ABAP和Java里的单例模式攻击
  • 原文地址:https://www.cnblogs.com/lyl-312/p/5535778.html
Copyright © 2011-2022 走看看