排序算法综述

排序算法有很多种,本文主要介绍基本的排序算法和实现,并分析复杂度和稳定性。

一、Ο(n2)的算法

  1、插入排序

  插入排序十分好理解,在无序的数组中选择一个数值,插入到有序的数组当中,这个过程是稳定的。实现代码如下:

  

1 template <typename T>
2 void InsertionSort(vector<T> &arr){
3     int i, j;
4     for (i = 1; i < arr.size(); i++) {
5         int temp = arr[i];
6         for (j = i - 1; j >= 0 && arr[j] > temp; j--)
7             arr[j + 1] = arr[j];
8         arr[j + 1] = temp;
9     }

InsertionSort

  2、冒泡排序

  冒泡排序的过程是遍历数组,每次选取一个数值往前比较,大于前一个数值就交换,直到遇到更大的数值或遍历完数组,这个过程本身也是稳定的。

template <typename T>
void BubbleSort(vector<T> &arr){
    for (int i = 0; i != arr.size(); i++){
        for (size_t j = 0; j < arr.size()-1-i ; j++)
        {
            if (arr[j] > arr[j + 1]){
                arr[j] = arr[j] ^ arr[j+1];
                arr[j+1] = arr[j] ^ arr[j+1];
                arr[j] = arr[j+1] ^ arr[j];
            }
        }
    }
}

BubbleSort

二、Ο(nlogn)的算法

  1、归并排序

    归并排序是典型的分治算法,把原问题划分为不相交的子问题。代码如下:

    

 1 void Merge(vector<int> &arr,int l,int m,int r){
 2     vector<int> Left, Right;
 3     int n1 = m - l; int n2 = r - m;
 4     for (int i = 0; i <= n1 ; i++)
 5         Left.push_back(arr[l + i]);
 6     Left.push_back(infinite);//哨兵值
 7     for (int i = 0; i != n2; i++)
 8         Right.push_back(arr[m + i + 1]);
 9     Right.push_back(infinite);
10     int index1 = 0;int index2 = 0;
11     for (int i = l; i != r + 1; i++){
12         if (Left[index1] < Right[index2])
13             arr[i] = Left[index1++];
14         else
15             arr[i] = Right[index2++];
16     }
17 };
18
19
20 void MergeSort(vector<int> &arr, int l, int r){
21
22     if (l < r){
23         int m = int((l + r) / 2);
24         MergeSort(arr, l, m);
25         MergeSort(arr, m + 1, r);
26         Merge(arr, l, m, r);
27     }
28 }

MergeSort

  2、堆排序

    堆排的本质就是维护一个最大堆(最小堆),所以他的时间复杂度是与最大堆的性质相联系的,一个最大堆的Deletemax操作是O(1)的,而每次DeleteMax后要维护最大                堆的性质,所以维护堆的时间复杂度是O(logn)的,合起来就是O(nlogn)。代码实现与建堆类似,就不赘述。

    

  3、快速排序

    快排也是分治的思想,选取一个主元,将数组分为两个部分,一个部分小于它另一个部分大于它,然后递归两个子数组直到排序完成。快排和主元的选取有关,如果选取的        结果恰好是排好序的,那么时间复杂度将会变成O(n2)。

    代码如下:

    

 1 int Partition(vector<int> &arr, int left, int right){
 2     int i = left - 1;
 3     for (int j = left; j < right; j++){
 4         if (arr[j] <= arr[right])
 5             std::swap(arr[++i], arr[j]);
 6     }
 7     std::swap(arr[i + 1], arr[right]);
 8     return i + 1;
 9 }
10 void QuickSort(vector<int> &arr,int left,int right){
11     if (left < right){
12         int mid = Partition(arr, left, right);
13         QuickSort(arr, left, mid-1);
14         QuickSort(arr, mid+1, right);
15     }
16
17 }

三、线性算法(以后介绍)

  

  1、基数排序

  2、计数排序

  3、桶排序

时间: 2024-10-24 13:33:58

排序算法综述的相关文章

排序算法-综述

1.冒泡排序算法: 冒泡排序算法是最简单也是最基本的排序算法之一,算法的原理为如下: 原理:将数据当中的每一个元素与之后的元素进行对比,如果当前元素比序列后的元素的值小,则交换两者的顺序,依次类推,直到最后一个数据完成排序即可! 时间复杂度:O(n2)  API实现如下(两层for循环嵌套实现): 1 int BubbleSort(int *In, int N) 2 { 3 int temp; 4 for (int i = 0; i < N; i++) { 5 for (int j = i +

搜索引擎网页排序算法

2.1基于词频统计——词位置加权的搜索引擎 利用关键词在文档中出现的频率和位置排序是搜索引擎最早期排序的主要思想,其技术发展也最为成熟,是第一阶段搜索引擎的主要排序技术,应用非常广泛,至今仍是许多搜索引擎的核心排序技术.其基本原理是:关键词在文档中词频越高,出现的位置越重要,则被认为和检索词的相关性越好. 1)词频统计 文档的词频是指查询关键词在文档中出现的频率.查询关键词词频在文档中出现的频率越高,其相关度越大.但当关键词为常用词时,使其对相关性判断的意义非常小.TF/IDF很好的解决了这个问

Java实现排序算法之归并排序

一.综述 归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 算法描述 归并操作的过程如下: 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 设定两个指针,最初位置分别为两个已经排序序列的起始位置 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 重复步骤3直到某一指针达到序列尾 将另一序列剩下的所有元素直接复制到合并序列尾

算法导论专题一--排序算法

排序算法作为许多程序的中间步骤,是计算机科学中的一个基本操作. 一.问题描述 排序算法输入的是n个数的一个序列<a1,a2…..an>,输出为输入的一个排列<a1’,…..an’>,满足a1’<a2’<….<an’ 简言之就是输入一个序列,输出的是这个数组元素从小到大排列的另一序列. 二.方法思想综述 从算法导论这本书上根据算法的复杂度可以将排序算法分为三种,,.,这两种方法都需要数据间的比较,而不需要. 其中有三种为选择,冒泡,插入. 选择排序:最直观,简单但是

网格聚类算法综述

网格聚类算法综述 (1)STING STING(Statistical Information Grid)是一种基于网格的多分辨率聚类技术它将空间区域划分为矩型单元.针对不同级别的分辨率,通常存在多个级别的矩形单元,这些单元形成了一个层次结构:高层的每个单元被划分为多个低一层的单元.每个网格单元属性的统计信息(例如平均值.最大值和最小值)被预先计算和存储.这些统计信息对于下面描述的查询处理是有用的. STING有几个优点:(1)由于存储在每个单元中的统计信息提供了单元中的数据不依赖查询的汇总信息

算法导论专题一--排序算法(2)

上节分析了O(n^2)的算法,这节就分析O(nlgn)的算法-归并,快速和堆排序. 一:综述 O(nlgn) 的算法可以分为两大类,两者所用的技术差别较大.归并和快速排序采用的是分治策略,这两者相当于一个对称的过程,一个是自顶向上合并子问题,另一个则自上向下分解子问题.而堆排序利用堆这一数据结构元素间的特殊关系来排序一个序列,另外采用二叉树的方式组织数据使其效率大大提高. 二:分治策略排序算法 1.为什么使用分治? 在上节算法的分析中,不管是冒泡.选择还是插入都不适用于大规模的数据,因为数据一大

九种经典排序算法详解(冒泡排序,插入排序,选择排序,快速排序,归并排序,堆排序,计数排序,桶排序,基数排序)

综述 最近复习了各种排序算法,记录了一下学习总结和心得,希望对大家能有所帮助.本文介绍了冒泡排序.插入排序.选择排序.快速排序.归并排序.堆排序.计数排序.桶排序.基数排序9种经典的排序算法.针对每种排序算法分析了算法的主要思路,每个算法都附上了伪代码和C++实现. 算法分类 原地排序(in-place):没有使用辅助数据结构来存储中间结果的排序**算法. 非原地排序(not-in-place / out-of-place):使用了辅助数据结构来存储中间结果的排序算法 稳定排序:数列值(key)

经典排序算法 - 冒泡排序Bubble sort

 原文出自于 http://www.cnblogs.com/kkun/archive/2011/11/23/bubble_sort.html 经典排序算法 - 冒泡排序Bubble sort 原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换, 这样一趟过去后,最大或最小的数字被交换到了最后一位, 然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子 例子为从小到大排序, 原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 | 第一趟排序(外循环) 第

排序算法比较及其应用

一.将各种数据排序 只要实现了Comparable接口的数据类型就可以被排序. 但要使算法能够灵活地用不同字段进行排序,则是后续需要考虑的问题. 1.指针排序 在Java中,指针操作是隐式的,排序算法操作的总是数据引用,而不是数据本身. 2.键不可变 如果在排序后,用例还可以改变键值,那么数组很可能就不是有序的了.类似,优先队列也会乱套. Java中,可以用不可变数据类型作为键来避免这个问题,如String,Integer,Double和File都是不可变的. 3.廉价交换 使用引用的另一个好处