zoukankan      html  css  js  c++  java
  • 各种排序算法比较

    排序相关的算法复杂度分析

    下边分别实现下各个算法

    简单选择排序

     1 //简单选择排序
     2 void Select_Sort(int a[], int n)
     3 {
     4     int min;
     5     for(int i = 0; i < n; i++)
     6     {
     7         int index = i;
     8         min = a[i];
     9         for(int j = i; j < n; j++)
    10         {
    11             if(a[j] < min)
    12             {
    13                 min = a[j];
    14                 index = j;
    15             }
    16         }
    17         swap(a[i], a[index]);
    18     }
    19 }

    这里简单选择排序之所以不稳定是因为交换的时候会打乱顺序,例如 5,4,5,1,6。第一次交换后会是1,4,5,5,6.已经破坏了稳定性。

    算法复杂度很明显是O(n^2);

    冒泡排序

     1 // 冒泡排序
     2 void Bubble_Sort(int a[], int n)
     3 {
     4     for(int i = n - 2; i >= 0; i--)
     5     {
     6         int flag = 0;
     7         for(int j = 0; j <= i; j++)
     8         {
     9             if(a[j] > a[j+1])
    10             {
    11                 swap(a[j], a[j+1]);
    12                 flag = 1;
    13             }
    14         }
    15 
    16         if(flag == 0) return ;
    17     }
    18 }

    冒泡排序中有两点需要注意的。第一它与简单选择排序相比其最好的时间复杂度是O(n)。第二 它是稳定性的算法,因为它每次只交换相邻的元素。

    只交换相邻的元素这个特点也让它可以使用于链表这个数据结构。

    插入排序:

     1 //插入排序
     2 void Insertion_Sort(int a[], int n)
     3 {
     4     for(int i = 1; i < n; i++)
     5     {
     6         int tmp = a[i];
     7         int j;
     8         for(j = i-1; (j >= 0) && (a[j] > tmp); j--)
     9         {
    10             a[j+1] = a[j];
    11         }
    12         a[j+1] = tmp;
    13     }
    14 }

    插入排序最好的情形也是O(n)。

    希尔排序就不实现了,这个排序的时间复杂度与具体的间隔选取之间有关。

    堆排序(伪代码):

     1 //堆排
     2 int main(void)
     3 {
     4     int a[] = {2,33,6,88,55,33,4,5,67,1,25};
     5     vector<int> heap(a, a + sizeof(a)/sizeof(int));
     6     Build(heap);
     7     vector<int>s;
     8     int maxindex = heap.size();
     9     for(int i = 0; i < maxindex; i++)
    10     {
    11         s.push_back(heap[0]);
    12         swap(heap[0],heap[heap.size()-1]);
    13         heap.pop_back();
    14         int index = 0;
    15         while((2*index+1) < heap.size())
    16         {
    17             int min_index = index;
    18             if(heap[min_index] > heap[2*index+1])
    19             {
    20                 min_index = 2 * index + 1;
    21             }
    22             if((2 * index + 2) < heap.size())
    23             {
    24                 if(heap[min_index] > heap[2*index + 2])
    25                     min_index = 2 * index + 2;
    26             }
    27             swap(heap[min_index], heap[index]);
    28             if(index == min_index)
    29                 break;
    30             else
    31                 index = min_index;
    32         }
    33         
    34     }
    35 
    36     return 0;
    37 }
    38 
    39 void Build(vector<int> &heap)
    40 {
    41     int index = 0;
    42     int max = heap.size() / 2 -1;
    43 
    44     for(int i = max; i >= 0; i--)
    45     {
    46         int index = i;
    47         while((2*index+1) < heap.size())
    48         {
    49             int min_index = index;
    50             if(heap[min_index] > heap[2*index+1])
    51             {
    52                 min_index = 2 * index + 1;
    53             }
    54             if((2 * index + 2) < heap.size())
    55             {
    56                 if(heap[min_index] > heap[2*index + 2])
    57                     min_index = 2 * index + 2;
    58             }
    59             swap(heap[min_index], heap[index]);
    60             if(index == min_index)
    61                 break;
    62             else
    63                 index = min_index;
    64         }
    65     }
    66     return ;

    堆排序是基于选择排序的思想上提出的。这里利用实现更快的寻找最大最小值。其复杂度为O(nlgn)。它与简单选择排序相比编码较繁琐。

    快速排序

     1 void Quick_sort(int a[], int begin, int end)
     2 {
     3     if(begin >= end)
     4         return ;
     5     int slot = end;
     6     int first = begin, last = slot-1;
     7     while(1)
     8     {
     9         while((a[first] <= a[slot]) && (first < end))
    10             first++;
    11         while((a[last] > a[slot]) && (last > 0))
    12             last--;
    13         if(first < last)
    14             swap(a[first], a[last]);
    15         else
    16             break;
    17     }
    18     swap(a[first],a[slot]);
    19     
    20     Quick_sort(a, begin, first-1);
    21     Quick_sort(a, first+1, end);
    22 }

    快排比较排序中平均速度最快的一种,但是如果选择的主元不合适,会退化为n^2的复杂度。

    归并排序

     1 void Divide_conquer_sort(int a[], int begin, int end)
     2 {
     3     if(begin >= end)
     4         return ;
     5     int mid = (begin + end) / 2;
     6     Divide_conquer_sort(a,begin, mid);
     7     Divide_conquer_sort(a, mid+1,end);
     8     vector<int> store;
     9     int first_begin = begin, second_begin = mid+1;
    10 
    11     while((first_begin <= mid) && (second_begin <= end))
    12     {
    13         if(a[first_begin] < a[second_begin])
    14         {
    15             store.push_back(a[first_begin]);
    16             first_begin++;
    17         }
    18         else
    19         {
    20             store.push_back(a[second_begin]);
    21             second_begin++;
    22         }
    23     }
    24 
    25     while(first_begin <= mid)
    26         store.push_back(a[first_begin++]);
    27     while(second_begin <= end)
    28         store.push_back(a[second_begin++]);
    29     for(int i = 0; i < store.size(); i++)
    30         a[i+begin] = store[i];
    31 }

    归并排序相对于快排没有选择主元的问题,相应的也就没有最坏时间那么一说。其实还有一种使用空间是O(1)的归并排序,实现起来要稍微复杂点。

  • 相关阅读:
    SQL Server 阻止了对组件 'Ole Automation Procedures' 的 过程'sys.sp_OACreate' 的访问
    谷歌浏览器扩展程序manifest.json参数详解
    获取天气api
    UVA 10385 Duathlon
    UVA 10668 Expanding Rods
    UVALIVE 3891 The Teacher's Side of Math
    UVA 11149 Power of Matrix
    UVA 10655 Contemplation! Algebra
    UVA 11210 Chinese Mahjong
    UVA 11384 Help is needed for Dexter
  • 原文地址:https://www.cnblogs.com/qtalker/p/4623717.html
Copyright © 2011-2022 走看看