zoukankan      html  css  js  c++  java
  • 20.排序之冒泡、直插、希尔排序方法

    围观大神十大经典排序算法(动图演示)/*9. 排序

    为了讲清楚排序算法的代码,我先提供一个用于排序用的顺序表结构,此结构也将用于之后我们要讲的所有排序算法;
    */
    
    #define MAXSIZE 10
    typedef struct
    {
        //用于存储要排序数组,r[0]用作哨兵或临时变量
        int r[MAXSIZE + 1];
        //用于记录顺序表的长度
        int length;
    } SqList;
    
    //另外,由于排序最最常用到的操作是数组两元素的交换,我们将它写成函数,在之后的讲解中会大量的用到。
    
    //交换L中数组r的下标为i和j的值
    void swap(SqList *L, int i, int j)
    {
        int temp = L->r[i];
        L->r[i] = L->r[j];
        L->r[j] = temp;
    }
    
    /*
    9.3 冒泡排序
    
    冒泡排序(Bubble Sort)是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,
    直到没有反序的记录为止。 
    */
    //对顺序表L作交换排序(冒泡排序的初级版)
    void BubbleSort0(SqList *L)
    {
        int i,j;
        for(i=1; i < L->length; i++)
        {
            for(j = i+1; j < L->length; j++)
            {
                if(L->r[i] > L->r[j])
                {
                    //交换L->r[i]与L->r[j]的值
                    swap(L, i, j);
                }
            }
        }
    }
    /*
    这段代码严格意义上来说,不算是标准的冒泡排序算法,因为它不满足“两两比较相邻记录”的冒泡排序思想,
    他更应该是最最简单的交换排序而已。它的思路就是让每一个关键字,都和它后面的每一个关键字比较,如果
    大则交换,这样第一位置的关键字在一次循环后一定变成最小值。
    */
    
    //正宗的冒泡排序算法
    void BubbleSort(SqList *L)
    {
        int i,j;
        for(i=1; i < L->length; i++)
        {
            //这里j是从后往前循环,直到“最小值”将其移至第i的位置;当然你也可以让j=i从前向后循环,直到“最大值”将其移至第length-i的位置。
         for(j = L->length-1; j >= i; j--) { //若前者大于后者(注意这里与上一算法差异) if(L->r[j] > L->r[j+1]) { //交换L->r[j]与L->r[j+1]的值 swap(L, j, j+1); } } } } //冒泡排序优化 void BubbleSort2(SqList *L) { int i,j; //flag用来作为标记 Status flag = TRUE; //若flag为true说明有过数据交换,否则停止循环 for(i=1; i < L->length && flag; i++) { //初始化为false flag = FALSE; for(j = L->length-1; j >= i; j--) { if(L->r[j] > L->r[j+1]) { //交换L->r[j]与r[j+1]的值 swap(L, j, j+1); //如果有数据交换,则flag为true flag = TRUE; } } } } /* 9.4 简单选择排序 简单选择排序算法(Simple Selection Sort)就是通过n-i次关键字间的比较,从n-i+1个记录中选出关键字 最小的记录,并和第i(1<=i<=n)个记录交换之。 */ //对顺序表L作简单选择排序 void SelectSort(SqList *L) { int i,j,min; for (i = 1; i < L->length; i++) { //将当前下表定义为最小值下标 min = i; //循环之后的数据 for(j = i+1; j <= L->length; j++) { //如果有小于当前最小值的关键字 if(L->r[min] > L->r[j]) //将此关键字的下标赋值给min min = j; } //若min不等于i,说明找到最小值,交换 if(i != min) //交换L->r[i]与L->r[min]的值 swap(L, i, min); } } /* 简单选择排序复杂度分析 从简单选择排序的过程来看,它最大的特点就是交换移动数据次数相当少,这样也就节约了相应的时间。 分析它的时间复杂度发现,无论最好最差的情况,其比较次数都是一样的多性能上略优于冒泡排序。 */ /* 9.5 直接插入排序 直接插入排序(Straight Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中, 从而得到一个新的、记录数增1的有序表。 */ //对顺序表L作直接插入排序 //这个代码树上是有问题的吧? void InsertSort(SqList *L) { int i,j; //r[0]用作哨兵或临时变量,作用是作为交换元素的中介 r[1]为第一个数值元素 for(i=2; i <= L->length; i++) { //需将L->r[i]插入有序子表 if(L->r[i] < L->r[i-1]) { //设置哨兵,为要移动的元素 L->r[0] = L->r[i]; for(j=i-1; L->r[j] > L->r[0]; j--) //从后向前遍历 L->r[j+1] = L->r[j]; //交换位置 大元素后移 L->r[j+1] = L->r[0]; //交换位置 小元素前移 } } } /* 1.程序开始运行,此时我们传入的SqList参数的值为length=6,r[6]={0,5,3,4,6,2},其中r[0]=0将用于 后面起到哨兵的作用。 2. 第4~13行就是排序的主循环。i从2开始的意思是我们假设r[1]=5已经放置好位置,后面的牌其实就是插入 到它的左侧还是右侧的问题。 3.第6行,此时i=2,L->r[i]=3比L->r[i-1]要小,因此执行第8~11行的操作。第8行我们将L->r[0]赋值为 L->r[i]=3的目的是为了起到第9~10行的循环终止的判断依据... */ /* 9.6 希尔排序 希尔排序是对直接插入排序的改进版本,改进后可以增加效率,总的来说先粗分为几组(比如3组),再直插排序。 对直接插入排序的复杂度分析可得,最好的情况,也就是要排序的表本身就是有序的;如果排序记录是随机的, 那么根据概率相同的原则,平均比较和移动次数约为(n^2)/4次。因此我们得出直接插入排序法的时间复杂度为 O(n^2)。从这里也看出,同样的O(n^2)时间复杂度,直接插入排序法比冒泡和简单选择排序的性能要好一些。 因此让数据基本有序就成了提高直接插入排序算法的关键。 */ //希尔排序算法代码如下: void ShellSort(SqList *L) { int i,j; int increment = L->length; do { //增量序列 increment = increment / 3 + 1; for(i = increment + 1; i <= L->length; i++) { if(L->r[i] < L->r[i-increment]) { //需将L->r[i]插入有序增量子表 //暂存在L->r[0] L->r[0] = L->r[i]; for(j=i-increment; j>0 && L->r[0] < L->r[j]; j-=increment) //记录后移,查找插入位置 L->r[j+increment] = L->r[j]; //j+increament就是i //插入 L->r[j+increment] = L->r[0]; } } } while (increment > 1); }
  • 相关阅读:
    eclipse快捷键 Eclipse快捷键 10个最有用的快捷键
    ssh之雇员管理系统(5)将struts+spring整合2
    ssh之雇员管理系统(4)改进的hibernate测试
    java中常常建包时,这些包具体是什么意思呢?+项目开发流程、实战
    ssh之雇员管理系统(1)spring测试
    JUnit4概述
    ssh之雇员管理系统(5)添加struts测试
    SQl查询数据库表名、表的列名
    关于人脉大PK的二三事 推荐的方法
    JavaScript有用的代码(ie,save)
  • 原文地址:https://www.cnblogs.com/go-ahead-wsg/p/13290432.html
Copyright © 2011-2022 走看看