三、基于交换的排序算法(冒泡排序和快速排序)

1、冒泡排序

基本思想:若从小到大排序,从头开始,两两比较,大的放在后面,将待排序元素从左到右比较一遍成为“一次冒泡”,每次冒泡都将待排序数列中最大的关键字交换到最后,直到所有元素有序为止。

算法复杂度:O(2^n)

改进方法:可能排序几次后,数列已经有序,但是还没有进行完n次循环。可以在交换的代码段中设置一个标志位,如果该标志位改变说明有交换(还未有序),否则用break退出循环。

//1、冒泡排序
//注意数组下标溢出
void Bubble(int *array, int n)
{
    int temp = 0;
    for (int i=0; i<n; ++i)
    {
        for (int j=0; j<n-i; ++j)
        {
            if (array[j-1]>array[j])
            {
                temp = array[j];
                array[j] = array[j-1];
                array[j-1] = temp;
            }
        }
    }
    for (int m=0; m<n; ++m)
    {
        cout<<array[m]<<‘ ‘;
    }
    cout<<endl;

}
//改进冒泡排序:可能在第i次后,已经有序,则在j循环中设置标志
//如果该次没有交换,说明已经有序
void BubbleAdvanced(int *array, int n)
{
    int temp = 0;
    int i;
    bool exchange_flag = true;
    for (i=0; i<n; ++i)
    {
        exchange_flag = false;
        for (int j=0; j<n-i; ++j)
        {
            if (array[j-1]>array[j])
            {
                temp = array[j];
                array[j] = array[j-1];
                array[j-1] = temp;
                exchange_flag = true;
            }
        }
        if (exchange_flag == false)
        {
            break;
        }
    }

    for (int m=0; m<n; ++m)
    {
        cout<<array[m]<<‘ ‘;
    }
    cout<<endl;
    cout<<i<<endl;
}

2、快速排序

基本思想:递归

(1)从数列中取出一个数,作为基准数;(基准数一般取:左边第一个元素/中间的元素/最大和最小数的平均值)

(2)分成两部分:将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边;

(3){左边小}基准数{右边大},再对左右两边重复第二步,直到各区间只有一个数。

快速排序是一种不稳定的算法,不稳定:在排序过程中,对关键字a排序会改变其他关键字的顺序,不稳定出现在有相同数字时。

如:27(a),23,27(b),3

以第一个27(a)为基准值,则27(a)与3交换,变成3,23,27(b),27(a)

两个27原来的顺序改变了,所以不稳定。

void QuickSort(int array[], int left, int right)
{
    int i = left;
    int j = right;
    int midValue = array[(left+right)/2];
    int temp;
    do
    {
        //找出左边第一个比基准值大的数
        while(i<right  && array[i]<midValue)
        {
            ++i;
        }
        //找出右边第一个比基准值小的数
        while(j>left && array[j]>midValue)
        {
            --j;
        }
        //上面找出的两个数交换
        if (i<=j)
        {
            temp = array[i];
            array[i] = array[j];
            array[j] = temp;
            ++i;
            j--;
        }
        //交换以后继续上述过程,再交换
    }while(i<j);
    //Print(array, right+1);
    //形成{左边小}基准值{右边大}
    //递归,直到左右区间只有一个值
    if (j>left)
    {
        QuickSort(array, left, j);
    }
    if (i<right)
    {
        QuickSort(array, i, right);
    }

}

(在快速排序编程中,出现的问题:与基准值比较是否取“=”,i与j比较是否取“=”,实在搞不清。)

快速排序复杂度:O(n*lgn) (以2为底)

  每次调用该函数:需要遍历该数组,复杂度是O(n);

  递归调用该函数:调用lgn次(以2为底),所以O(n)*O(lgn)=O(n*lgn) 。

快速排序算法的递推公式:F(n)=2*F(n/2)+n

  F(n)=2*F(n/2)+n =2*(2*F(n/4)+n/2)+n =4*F(n/2)+2*n =…… =k*F(1) +lgn*n

快速排序复杂度参考资料:http://book.51cto.com/art/201108/287089.htm

http://zhidao.baidu.com/link?url=

QAD5ZIcnFZ5MkQiFvg03EZMOxkdbU45K99vBHM3s48zmiT3zhfyt2jlUy3WmVcIxSyIXrqtA0S2NuxfVfKfIadfm3RljFXWUQVgtT7QVJMK

快速排序参考资料:http://blog.csdn.net/liuchen1206/article/details/6954074

时间: 2024-08-05 11:18:47

三、基于交换的排序算法(冒泡排序和快速排序)的相关文章

基于相邻元素交换的排序算法的下界

逆序(inversion)是指序列中具有性质“i<j,但a[i]>a[j]“的序偶(a[i].a[j]). 例如:在序列34,8,64,51,32,21中具有9个逆序:(34,8),(34,32),(34,21),(64,51),(64,32),(64,21),(51,32),(51,21),(32,21): 显而易见的是,排序完成之后,序列中将不会存在逆序.因此我们可以通过计算序列中的逆序数来及算排序平均运行时间的精确的界.为了可以定义出“平均”,这里假设序列中不存在重复元素.利用这个假设,

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

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

排序算法—冒泡排序

*/--> 排序算法-冒泡排序 Table of Contents 1 问题描述 2 冒泡排序(Bubble) 2.1 冒泡排序(一) 2.2 冒泡排序(二) 2.3 冒泡排序(三) 2.4 冒泡排序(四) 3 阅读参考 1 问题描述 引子 排序是数据结构中十分重要的一章,排序算法有很多种,一直没时间整理而且很多排序算法理解的也不是很透彻.希望通过这次整理吃透吧! 排序算法十分多,故分篇进行整理. 说明 本文重点是理解排序算法,而不是完整的程序,所以每节都只有具体排序算法的接口.没有完整的源代码

[C#] 用菜鸟的思维学习算法 -- 马桶排序、冒泡排序和快速排序

用菜鸟的思维学习算法 -- 马桶排序.冒泡排序和快速排序 [博主]反骨仔 [来源]http://www.cnblogs.com/liqingwen/p/4994261.html  马桶排序 一.场景:期末考试完了,老师要将同学们的分数从高到低排序.假设班上有 5 名同学,分别考了 5 分.3 分.5 分.2 分和 8 分[满分:10 分],排序后的结果就是 8 5 5 3 2,现在,让我们先思考 10 分钟吧! 二.思路: (1)先创建一个数组 int scores[11],就有 scores[

非基于比较的排序算法之一:计数排序

计数排序(Counting sort)是一种稳定的排序算法.计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值小于等于i的元素的个数.然后根据数组C来将A中的元素排到正确的位置. 限制:所有值得取值范围不能太大,并且需要知道确切的取值范围.本算法需要的辅助空间要求较高. 当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 Θ(n + k).计数排序不是比较排序,排序的速度快于任何比较排序算法. 现在给出C#实现的计数排序(counting sort) public vo

图形化排序算法比较:快速排序、插入排序、选择排序、冒泡排序

图形化排序算法比较:快速排序.插入排序.选择排序.冒泡排序

Python八大算法的实现,插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。

Python八大算法的实现,插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2).是稳定的排序方法.插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素).在第一部分排序完成后,再将这

排序算法学习之快速排序

快速排序基本思想:选取一个枢轴元素(图简单可选第一个),通过对序列一次遍历(中间涉及到数的交换),将该枢轴放置到序列合适位置,保证其左边数都比它小,右边数都比它大,然后利用递归思想对其左右两个子序列进行同样排序. 快熟排序的基本实现过程:将枢轴元素key备份,序列头尾各设置一个游标--i和j,尾部游标j先移动(如果选择的最后一个元素为枢轴则i先移),直到遇到比key小的元素,将其移到原枢轴处覆盖之,此时j处元素空着了,然后再对i进行移动,直到遇到比key大的元素,将其移到右边下表为j的空白处 v

三个典型的经典算法冒泡排序,插入排序,选择排序

稍微轻松点,彻底理解了一下这三个算法,当然只是部分,还有什么改良版,具体分类等等,不过下周有事,先把这几个典型的弄明白,老规矩,看代码说问题 /** * Created by fanyafeng on 2015/5/8/0008. */ public class ALGTest { public static void main(String[] args) { System.out.println("排序算法"); System.out.println("---------