`
qiemengdao
  • 浏览: 276489 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

排序算法大赏(未完待续)

 
阅读更多

一、前言

排序算法也是面试中常常提及的内容,问的最多的应该是快速排序、堆排序。这些排序算法很基础,但是如果平时不怎么写代码的话,面试的时候总会出现各种bug。虽然思想都知道,但是就是写不出来。本文打算对各种排序算法进行一个汇总,像插入排序、冒泡排序、选择排序等就简单的介绍,重点关注快速排序和堆排序。需要提到的一点就是:插入排序,冒泡排序,归并排序,计数排序都是稳定的排序,而其他排序则都是不稳定的。

二、简单排序

1)插入排序

插入排序是很基本的排序,特别是在数据基本有序的情况下,插入排序的性能很高,基本可以达到O(N)。当然其最坏情况和平均情况时间复杂度都是O(N^2)。代码如下:
void insert_sort(int x[], int n)
{
    int i, j;
    for (i=1; i<n; i++) {
        /*循环不变式:x[0...i-1]有序。每次迭代开始前,x[0...i-1]有序, 循环结束后i=n,x[0...n-1]有序*/
        int key = x[i];
        for (j=i; j>0 && x[j-1]>key; j--) {
            x[j] = x[j-1];
        }
        x[j] = key;
    }
}

2)选择排序

选择排序的思想就是第i次选取第i小的元素放在位置i。比如第1次就选择最小的元素放在位置0,第2次选择第二小的元素放在位置1。选择排序最好和最坏时间复杂度都为O(N^2)。代码如下:
void select_sort(int x[], int n)
{
    int i, j, min, tmp;
    for (i=0; i<n-1; i++) {
        min = i;
        for (j=i+1; j<n; j++) {
            if (x[j] < x[min])
                min = j;
        }
        if (min != i)
            tmp = x[i], x[i] = x[min], x[min] = tmp;//交换x[i]和x[min]
    }
}
循环不变式:在外层循环执行前,x[0...i-1]包含a中最小的i个数,且有序。
初始时,i=0,x[0...-1]为空,显然成立。
每次执行完成后,x[0...i]包含x中最小的i+1个数,且有序。即第一次执行完成后,x[0...0]包含x最小的1个数,且有序。
循环结束后,i=n-1,则x[0...n-2]包含x最小的n-1个数,且已经有序。所以整个数组有序。

3)冒泡排序
冒泡排序时间复杂度跟选择排序相同。其思想就是进行n-1趟排序,每次都是把最小的数上浮,像鱼冒泡一样。最坏情况为O(N^2)。代码如下:
void bubble_sort(int x[], int n)
{
    int tmp;
    for (int i=0; i<n; i++) {
        for (int j = n-1; j>=i+1; j--) {
            if (x[j] < x[j-1])
                tmp = x[j], x[j] = x[j-1], x[j-1] = tmp;
        }   
    }   
}
循环不变式:在循环开始迭代前,子数组x[0...i-1]包含了数组x[0..n-1]i-1个最小值,且是排好序的。
对冒泡排序的一个改进就是在每趟排序时判断是否发生交换,如果一次交换都没有发生,则数组已经有序,可以不用继续剩下的趟数直接退出。改进后代码如下:
void bubble_sort_better(int x[], int n)
{
    int tmp;
    for (int i=0; i<n; i++) {
        int sorted = 1;
        for (int j = n-1; j>=i+1; j--) {
            if (x[j] < x[j-1]) {
                tmp = x[j], x[j] = x[j-1], x[j-1] = tmp;
                sorted = 0;
            }   
        }   
        if (sorted)
            return ;
    }   
}

4)计数排序

假定数组为A[0...n-1],数组中存在重复数字,数组中最大数字为k,建立两个辅助数组B和C,B用于存储排序后的结果,C用于存储临时值。时间复杂度为O(N),适用于数字范围较小的数组。具体见代码:
const int N = 5; //数字个数
int b[N+1];
void count_sort(int a[], int n, int k) //k为数组最大数字
{
    int c[k+1];  //辅助数组
    for (int i=0; i<=k; i++)
        c[i] = 0;
    for (int j=0; j<n; j++)
        c[a[j]] = c[a[j]] + 1; //C[i]包含等于i的元素个数

    for (int i=1; i<=k; i++)
        c[i] = c[i] + c[i-1];  //C[i]包含小于等于i的元素个数

    for (int j=n-1; j>=0; j--) {
        b[c[a[j]]] = a[j]; //结果存在B[1...N]中
        c[a[j]] = c[a[j]] - 1;
    }
}

5)归并排序

归并排序通过分治算法,先排序好两个子数组,然后将两个子数组归并。时间复杂度为O(NlgN)。代码如下:

/*归并排序代码*/
void merge_sort(int a[], int p, int r) 
{
	if (p < r) {
		int q = p+(r-p)/2;
		merge_sort(a, p, q);
		merge_sort(a, q + 1, r);
		merge(a, p, q, r);
	}
}

void merge(int a[], int start, int mid, int end) 
{
	int n1 = mid - start + 1;
	int n2 = end - mid;
	int left[n1], right[n2];
	int i, j;
	for (i = 0; i < n1; i++) /* left holds a[start..mid] */
		left[i] = a[start + i];
	for (j = 0; j < n2; j++) /* right holds a[mid+1..end] */
		right[j] = a[mid + 1 + j];
	i = j = 0;
	int k = start;
	while (i < n1 && j < n2) {
		if (left[i] < right[j])
			a[k++] = left[i++];
		else
			a[k++] = right[j++];
	}
	while (i < n1) /* left[] is not exhausted */
		a[k++] = left[i++];
	while (j < n2) /* right[] is not exhausted */
		a[k++] = right[j++];
}

三、堆排序



分享到:
评论

相关推荐

    各种排序算法比较(java实现)

    本文将详细探讨标题所提及的几种排序算法:合并排序、插入排序、希尔排序、快速排序、冒泡排序以及桶排序,并结合Java语言的实现进行解析。 1. **合并排序(Merge Sort)**: 合并排序是一种基于分治策略的排序算法...

    常用排序算法总结 常用排序算法总结 常用排序算法总结

    常用排序算法总结常用排序算法总结常用排序算法总结常用排序算法总结常用排序算法总结常用排序算法总结常用排序算法总结常用排序算法总结常用排序算法总结常用排序算法总结

    Verilog/C++实现排序算法:Verilog/C++实现排序算法:冒泡排序、选择排序、并行全比较排序、串行全比较排序

    本文将探讨如何使用这两种语言实现几种基本的排序算法:冒泡排序、选择排序,以及两种全比较排序(并行和串行)。 首先,让我们了解一下排序算法。排序是计算机科学中最基础的操作之一,它涉及到将一组数据按照特定...

    排序算法(C语言实现)

    在计算机科学中,排序算法是数据结构领域的重要组成部分,它涉及到如何有效地重新排列一组数据,使其按照特定的顺序排列。本资源提供了三种经典的排序算法的C语言实现:堆排序、直接插入排序和快速排序。 首先,让...

    算法设计与分析-1排序算法性能分析-冒泡/选择/插入/合并/快速排序-pre ppt

    本篇文章将详细讨论几种常见的排序算法:选择排序、冒泡排序、插入排序、合并排序以及快速排序,分析它们的算法原理、时间效率,并通过经验分析验证理论分析的准确性。 **1. 选择排序(Selection Sort)** 选择排序...

    Android-Android图形化展示排序算法

    在Android应用中实现图形化排序算法,首先需要了解各种基本的排序算法,例如冒泡排序、选择排序、插入排序、快速排序、归并排序以及堆排序等。这些算法各有特点,如冒泡排序的时间复杂度为O(n^2),适用于小规模数据...

    数据结构课程设计(内部排序算法比较_C语言)

    ### 数据结构课程设计:内部排序算法比较_C语言 #### 一、课题背景与意义 排序作为数据结构中的重要组成部分,在实际开发中具有广泛的应用场景。理解不同排序算法的特点及其适用场景,对于提高程序效率和解决问题...

    基于Qt5-实现九大排序算法的代码汇总

    在本文中,我们将深入探讨如何使用Qt5框架和C++编程语言实现九大经典的排序算法。Qt5是一个跨平台的应用程序开发框架,它提供了丰富的库和工具,使得开发人员能够便捷地构建用户界面和应用程序逻辑。C++则是一种强大...

    各种排序算法的实验(源代码+实验报告)

    3. **其他可能包含的排序算法**:除了快速排序和堆排序,这个资源可能还包含了其他的排序算法,如冒泡排序、插入排序、选择排序、归并排序、希尔排序、计数排序、桶排序、基数排序等。这些算法各有特点,适用于不同...

    数据结构内部排序算法比较.doc

    本次实验的主要目的是通过实际操作来比较六种常用的内部排序算法(起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序)在处理随机数据时的关键字比较次数和关键字移动次数,以便直观地了解每种算法...

    内部排序算法比较 课程设计

    【内部排序算法比较课程设计】主要关注的是对六种经典的内部排序算法的性能对比,包括起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序和堆排序。这些算法是计算机科学中用于对数据进行排序的基础工具,各...

    用C语言实现常用排序算法

    本项目旨在实现并比较六种经典的排序算法——直接插入排序、折半插入排序、起泡排序、简单选择排序、堆排序以及2-路归并排序,使用C语言编程。为了全面评估这些算法,我们将在一组随机生成的30000个整数上运行它们,...

    排序算法实验报告

    希尔排序,冒泡排序、快速排序递归排序,快速排序非递归排序,快速排序改进算法

    C++实现希尔、快速、堆排序、归并排序算法

    在编程领域,排序算法是计算机科学中的重要组成部分,特别是在数据处理和算法效率分析上。本文将详细介绍C++中实现的希尔排序、快速排序、堆排序和归并排序这四种经典排序算法。 希尔排序,由Donald Shell于1959年...

    3种排序算法可视化程序 c++ 算法

    在这个C++实现的项目中,我们有三种经典的排序算法被可视化:冒泡排序、插入排序和选择排序。这些算法的可视化能够帮助我们更好地理解它们的工作原理。** ### 冒泡排序 冒泡排序是最基础的排序算法之一,它通过重复...

    FPGA并行快速排序算法-位宽可设

    在本文中,我们将深入探讨基于FPGA的并行快速排序算法,特别关注“位宽可设”的特性。这种算法能够高效地处理大量数据,并且在硬件实现上具有很高的灵活性。我们将从以下几个方面来阐述这个主题: 一、快速排序算法...

    排序算法的比较课程设计实验报告.pdf

    排序算法的比较课程设计实验报告 本实验报告的目的是比较和分析不同的排序算法,包括直接插入排序、冒泡排序、快速排序等,并对其进行实验和比较。本报告将详细介绍排序算法的原理、实现和实验结果,并对实验结果...

    7种常用排序算法实现(C++)(冒泡排序、选择排序、直接插入排序、希尔排序、堆排序、归并排序以及快速排序)

    这七种算法分别是:冒泡排序、选择排序、直接插入排序、希尔排序、堆排序、归并排序和快速排序。 1. **冒泡排序**: 冒泡排序是最基础的排序算法之一,通过重复遍历待排序序列,比较相邻元素并交换位置来实现排序...

    实现所有经典排序算法汇总

    在计算机科学领域,排序算法是数据处理中至关重要的一部分,它涉及到如何有效地重新排列一组数据,使其按照特定标准(如升序或降序)排列。以下是对标题和描述中提到的经典排序算法的详细解释: 1. **选择排序...

    7.1_内部排序算法排序.CPP

    1、常见排序算法实现(1-6选择几个算法练习) 1)问题描述:输入一组关键字序列分别实现下列排序。 (1)实现简单选择排序、直接插入排序和冒泡排序。 (2)实现希尔排序算法。 (3)实现折半插入排序。 ...

Global site tag (gtag.js) - Google Analytics