zoukankan      html  css  js  c++  java
  • 排序算法

    一 插入排序(Insertion sort)
       该算法比较直接,类比扑克牌排序,具体如下:
    1 桌面上的扑克牌始终是乱序的,手上的扑克牌始终是有序的;
    2 当从桌面上拿到一张扑克牌后,比较该张扑克牌与手中扑克牌的大小,并在合理的位置插入扑克牌;
    3 当桌面上所有扑克牌均在手上时,排序完成。

     1 void InsertionSort(std::vector<int>& unsorted, std::vector<int>& sorted)
     2 {
     3     int sz = unsorted.size();
     4     if (sz <= 0)
     5         return;
     6 
     7     for (int i = 1; i < sz; ++i)
     8     {
     9         for (int j = 0; j < i; ++j)
    10         {
    11             if (unsorted[i] < unsorted[j])
    12             {
    13                 int temp = unsorted[i];
    14                 for (int k = i; k > j; --k)
    15                     unsorted[k] = unsorted[k - 1];
    16                 unsorted[j] = temp;
    17             }
    18         }
    19     }
    20 
    21     sorted = unsorted;
    22 }

     该算法复杂度为N*N,运行效率很低。

    二 归并排序(Merge sort)
         针对单个元素数组,该数组是有序的;然后一次合并相邻的两个单元素数组,形成两个有序元素的数组;继续以上过程,直到合并为整个大数组。
         假设待排序数组为array[N],其算法如下:
      1 对数组进行第一次扫描,使array[0...1]有序,...,使array[N-2...N-1]有序;
      2 对1形成的新数组进行第二次扫描,使array[0...3]有序,...,使array[N-4...N-1]有序;
      3 对2形成的新数组进行第三次扫描,使array[0...7]有序,...,使array[N-8...N-1]有序;
      4 重复以上过程,直到整个数组有序。

     1 void MergeSort(std::vector<int>& unsorted, std::vector<int>& sorted)
     2 {
     3     int sz = unsorted.size();
     4     if (sz <= 0)
     5         return;
     6 
     7     int merge_sz = 1;
     8     int src_idx = 0;
     9     std::vector<int> temp[2];
    10     temp[0] = unsorted;
    11     while (merge_sz < sz)
    12     {
    13         int dst_idx = 1 - src_idx;
    14         temp[dst_idx].clear();
    15         for (int i = 0; i < sz; i += merge_sz * 2)
    16         {
    17             int start1 = i;
    18             int end1 = start1 + merge_sz < sz ? start1 + merge_sz : sz;
    19             int start2 = end1;
    20             int end2 = start2 + merge_sz < sz ? start2 + merge_sz : sz;
    21             while (start1 < end1 || start2 < end2)
    22             {
    23                 if (start1 < end1 && start2 < end2)
    24                 {
    25                     if (temp[src_idx][start1] < temp[src_idx][start2])
    26                     {
    27                         temp[dst_idx].push_back(temp[src_idx][start1]);
    28                         ++start1;
    29                     }
    30                     else
    31                     {
    32                         temp[dst_idx].push_back(temp[src_idx][start2]);
    33                         ++start2;
    34                     }
    35                 }
    36                 else
    37                 {
    38                     if (start1 < end1)
    39                     {
    40                         for (int j = start1; j < end1; ++j)
    41                             temp[dst_idx].push_back(temp[src_idx][j]);
    42                         start1 = end1;
    43                     }
    44 
    45                     if (start2 < end2)
    46                     {
    47                         for (int j = start2; j < end2; ++j)
    48                             temp[dst_idx].push_back(temp[src_idx][j]);
    49                         start2 = end2;
    50                     }
    51                 }
    52             }
    53         }
    54 
    55         src_idx = 1 - src_idx;
    56         merge_sz *= 2;
    57     }
    58 
    59     sorted = temp[src_idx];
    60 }

       该算法时间复杂度为N*logN,运行效率较高。

    三 堆排序(heap sort)

      完全二叉树可以使用线性列表实现,最大堆(或最小堆)可以通过完全二叉树实现,这样就实现了对元素的线性访问。

      堆排序主要有以下内容:

      1 将乱序数组形成堆结构;

      2 成堆的线性数组的第一个元素即为最值元素;

      3 使用最后一个元素替换第一个元素,并抛弃最后一个元素;

      4 对3形成的新数组,不再满足堆条件(single violation),校正堆违例;

      5 进入2,直到堆中只有一个元素使退出。

     1 void HeapSort(std::vector<int>& unsorted, std::vector<int>& sorted)
     2 {
     3     int sz = unsorted.size();
     4     if (sz <= 0)
     5         return;
     6 
     7     // 构造max-heap
     8     for (int i = (sz - 1) / 2; i >= 0; --i)
     9     {
    10         // 子树构造max-heap
    11         int p = i;
    12         int l = p * 2 + 1;
    13         int r = l + 1;
    14         while (l < sz)
    15         {
    16             int max_idx = l;
    17             if (r < sz && unsorted[r] > unsorted[l])
    18                 max_idx = r;
    19             if (unsorted[max_idx] > unsorted[p])
    20             {
    21                 int temp = unsorted[p];
    22                 unsorted[p] = unsorted[max_idx];
    23                 unsorted[max_idx] = temp;
    24 
    25                 p = max_idx;
    26                 l = p * 2 + 1;
    27                 r = l + 1;
    28             }
    29             else
    30                 break;
    31         }
    32     }
    33 
    34     // 循环提取最大元素
    35     int heap_sz = sz;
    36     while (heap_sz > 1)
    37     {
    38         // 提取0位元素(最大数),并将末位元素填充到0位
    39         --heap_sz;
    40         int temp = unsorted[0];
    41         unsorted[0] = unsorted[heap_sz];
    42         unsorted[heap_sz] = temp;
    43 
    44         // 校正堆结构单违例(correct single violation)
    45         int p = 0;
    46         int l = p * 2 + 1;
    47         int r = l + 1;
    48         while (l < heap_sz)
    49         {
    50             int max_idx = l;
    51             if (r < heap_sz && unsorted[r] > unsorted[l])
    52                 max_idx = r;
    53             if (unsorted[max_idx] > unsorted[p])
    54             {
    55                 int temp = unsorted[p];
    56                 unsorted[p] = unsorted[max_idx];
    57                 unsorted[max_idx] = temp;
    58 
    59                 p = max_idx;
    60                 l = p * 2 + 1;
    61                 r = l + 1;
    62             }
    63             else
    64                 break;
    65         }
    66     }
    67 
    68     sorted = unsorted;
    69 }

       该算法时间复杂度为N*logN,运行效率较高。

  • 相关阅读:
    反转链表
    《Java JDK7 学习笔记》课后练习题1
    《Java JDK7 学习笔记》课后练习题2
    《java JDK7 学习笔记》课后练习题3
    SQL与NoSQL(关系型与非关系型)数据库的区别
    编程中编码的来源及发展
    JDK7学习笔记之基础类型
    《java JDK7学习笔记》之跨平台与路径设置
    《java jdk7学习笔记》之java三大平台
    VS2015安装之后加装SQL SERVER2014的步骤
  • 原文地址:https://www.cnblogs.com/luofeiju/p/10402088.html
Copyright © 2011-2022 走看看