精华内容
下载资源
问答
  • 给出一组关键字序列{29,18,25,47,58,12,51,10},分别给出用希尔排序、直接选择排序算法从小到大排序的结果。 参考施老师等编著的《数据结构》,本代码参考了赵同学的报告。 算法思想: 选择排序的基本思想是依次从待...

    给出一组关键字序列{29,18,25,47,58,12,51,10},分别给出用希尔排序、直接选择排序算法从小到大排序的结果。

    参考施老师等编著的《数据结构》,本代码参考了赵同学的报告。
    算法思想:
    选择排序的基本思想是依次从待排序记录序列中选择出关键字值最小(或最大)的记录、关键字值次之的记录、……,并分别将它们交换到序列的第1个位置、第2个位置、……,从而使记录成为按关键字值由小到大(或由大到小)顺序排列。
    希尔排序的基本思想(1)将待排序的记录划分成若干个子序列,分别进行直接插入排序(2)再划分几个大的子序列,进行直接插入排序;反复进行几遍 (3)最后作为一个完整的序列,实施直接插入排序*

    #include<stdio.h>//蓝多多算法实验八
    #define MAXSIZE 20
    typedef int KeyType;
    typedef struct {
    	KeyType key;
    }RedType;
    typedef struct {
    	RedType r[MAXSIZE + 1];
    	int length;
    }SqList;
    void ShellInsert(SqList& L, int dk);//希尔插入
    void ShellSort(SqList& L);//希尔排序
    void SelectSort(SqList& L);//直接选择排序
    int main()
    {
    	SqList L;
    	int i;
    	printf_s("input 8 elements:");
    	for (i = 1; i <= 8; i++)
    		scanf_s("%d", &L.r[i].key);
    	L.length = 8;
    	ShellSort(L);
    	printf_s("input the ordList(ShellSort):\n");
    	for (i = 1; i <= 8; i++)
    		printf_s("%5d", L.r[i].key);
    	printf_s("\n");
    	SelectSort(L);
    	printf_s("input the ordList(SelectSort):\n");
    	for (i = 1; i <= 8; i++)
    		printf_s("%5d", L.r[i].key);
    	return 0;
    }
    void ShellInsert(SqList& L, int dk)//希尔插入
    {
    	int i, j;
    	for (i = dk + 1; i <= L.length; ++i)
    		if (L.r[i].key < L.r[i - dk].key) {
    			L.r[0] = L.r[i];
    			for (j = i - dk; j > 0 && (L.r[0].key < L.r[j].key); j -= dk)
    				L.r[j + dk] = L.r[j];
    			L.r[j + dk] = L.r[0];
    		}
    }
    void ShellSort(SqList& L)//希尔排序
    {
    	int k;
    	int dlta[4] = { 4,3,2,1 };
    	for (k = 0; k < 4; ++k)
    		ShellInsert(L, dlta[k]);
    }
    void SelectSort(SqList& L)//直接选择排序
    {
    	int i, j, t;
    	for (i = 1; i < L.length; ++i) {
    		for (j = i + 1; j < L.length + 1; ++j)
    			if (L.r[i].key > L.r[j].key) {
    				t = L.r[i].key;
    				L.r[i].key = L.r[j].key;
    				L.r[j].key = t;
    			}
    	}
    }
    

    运行结果:略 (VS2019 自己去运行吧)

    展开全文
  • 设一组初始记录关键字序列(5,2,6,3,8),以第一个记录关键字5为基准进行一趟快 速排序的结果为( )。 (A) 2,3,5,8,6 (B) 3,2,5,8,6 (C) 3,2,5,6,8 (D) 2,3,6,5,8
  • 快排的效率很快,但是我们很少知道如何利用它进行多关键字排序,比如我想对一个数组a[i][0]进行的一个元素进行主关键字排序,又想对a[i][1]进行次关键字排序。那么接下来就是解决这个问题的方法。 学过数据结构的...

      快排的效率很快,但是我们很少知道如何利用它进行多关键字排序,比如我想对一个数组a[i][0]进行的一个元素进行主关键字排序,又想对a[i][1]进行次关键字排序。那么接下来就是解决这个问题的方法。  

      学过数据结构的同学,应该知道快排的基本原理,就是将要排序的物品(不说成值,因为我们可能要排多维数组或者是结构体),就是每次将一个物品放到序列中最合适的位置,那么如何放,如果想要递增排序,就是前面的物品和后面的物品,谁大的放后面。所以通过这个原理就知道void qsort(void*, size_t, size_t, int*(const void*, const void*));这个函数传参数的时候为什么最后一个参数是一个函数了,真正进行排序交换的是qsort(),但是还需要一个比较两个物品的大小的操作,这个操作是需要用户自定义的,如果需要物品递增,那么这个比较函数cmp()返回的就是a>b[a-b]的true结果,这个时候排序的时候会把大的交换到后面。同理,要想物品递减,那么cmp()返回的就是a<b[b-a]了。

      现在关键的问题来了。

    如果排序仅仅是一个int a[N]的数组

    int cmp(const void *a,const void *b)
    {
        return *(int *)a-*(int *)b;
    }

    //我来解释一下为什么会 return *(int *)a-*(int *)b;这个,因为我们传进到cmp()的参数是单个物体的地址,在这里我们传的是一个存储int值的一个int类型的地址,为了保持cmp()函数的可以让任何类型的数组进行比较大小,所以再传入到cmp()里面就会被转为不可变的const 的空void类型的地址,所以当我们在这个函数内部要比较大小时,又必须将这个地址转换成存储Int类型的地址,然后去取这个地址的值进行大小比较。所以(int *)a是将这个存储空类型void的地址强转换为存储int类型的地址,而只得到这个地址是比较不了大小的,这个时候就必须比较这个存储这个地址的内容了,获得地址内容只要在地址之前加上*号就可以了即*(int*)a这个的实际意义。

    同理如果你要比较结构体数组,就需要在cmp内部把const void *a单个结构体成员的地址然后就是去结构体中需要比较大小的关键字了

    int cmp( const void *a ,const void *b) 
    {
    return (*(Node *)a).data > (*(Node *)b).data ? 1 : -1; //或者true,false
    }

    qsort(s,100,sizeof(s[0]),cmp);
    根据这个结构体我们,同理可推出比较多维数组,这里我们用二维数组的例子,用二维数组的第二个值作为排序的关键字
    int a[1000][2];
    qsort(a,1000,sizeof(int)*2,comp);
     
    intcomp(constvoid*a,constvoid*b)
     
    {
    return (( int *)a)[1]-(( int *)b)[1];
    }
    那么我们进一步思考,怎样才能是二维数组有主次关键字排序,比如我想以a[i][2]中以a[i][0]为主关键字排序,以a[i][1]为次关键字排序。
    其实很简单比较一个物品大小的操作在我们手上,我们只需在cmp()最后给一个比较两个物品的大小的结构给qsort()就可以了,所以我们可以这样做:
    1,如果主关键字不相等就比较主关键字的大小并返回结果。
    2,如果主关键字相等,就比较次关键字的大小并返回结果就可以了。
    例子:
    int cmp( const void *a , const void *b )
    {
    if( ((int *)a)[0]==((int *)b)[0] ) return ((int *)a)[1]-((int *)b)[1];
    else return ((int *)a)[0]-((int *)b)[0];
    }
    qsort(a[1],n,sizeof(a[1]),cmp);
    这个例子还用了一个方法是如何忽略数组中a[0]的值,直接以a[1]开始排序。
    那么结构体中多关键字排序就是一样的了。至此就可以利用快排达到理想的排序状态了。
     

    转载于:https://www.cnblogs.com/woshijishu3/p/3604589.html

    展开全文
  • 根据给定的关键字序列,运用快速排序算法对其进行排序。 输入格式: 8, 10, 5, 6, 3, 13 二、实验目的 掌握快速排序算法。 三、实验内容及要求 1、构造关键字序列的存储结构。 2、实现快速排序算法。
  • 快速排序算法——C/C++

    万次阅读 多人点赞 2019-06-12 22:55:14
    快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。 2、实现原理 2.1、设置两个变量 low、...

    快速排序

    1. 算法思想

    快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

    2. 实现原理

    2.1、设置两个变量 low、high,排序开始时:low=0,high=size-1。
    2.2、整个数组找基准正确位置,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面

    1. 默认数组的第一个数为基准数据,赋值给key,即key=array[low]。
    2. 因为默认数组的第一个数为基准,所以从后面开始向前搜索(high–),找到第一个小于key的array[high],就将 array[high] 赋给 array[low],即 array[low] = array[high]。(循环条件是 array[high] >= key;结束时 array[high] < key)
    3. 此时从前面开始向后搜索(low++),找到第一个大于key的array[low],就将 array[low] 赋给 array[high],即 array[high] = array[low]。(循环条件是 array[low] <= key;结束时 array[low] > key)
    4. 循环 2-3 步骤,直到 low=high,该位置就是基准位置。
    5. 把基准数据赋给当前位置。

    2.3、第一趟找到的基准位置,作为下一趟的分界点。
    2.4、递归调用(recursive)分界点前和分界点后的子数组排序,重复2.2、2.3、2.4的步骤。
    2.5、最终就会得到排序好的数组。

    3. 动态演示

    在这里插入图片描述

    在这里插入图片描述

    4. 完整代码

    三个函数
    基准插入函数:int getStandard(int array[],int low,int high)
    (返回基准位置下标)
    递归排序函数:void quickSort(int array[],int low,int high)
    主函数:int main()

    #include <stdio.h>
    #include <stdlib.h>
    
    void display(int* array, int size) {
        for (int i = 0; i < size; i++) {
            printf("%d ", array[i]);
        }
        printf("\n");
    }
    
    int getStandard(int array[], int i, int j) {
        // 基准数据
        int key = array[i];
        while (i < j) {
            // 因为默认基准是从左边开始,所以从右边开始比较
            // 当队尾的元素大于等于基准数据 时,就一直向前挪动 j 指针
            while (i < j && array[j] >= key) {
                j--;
            }
            // 当找到比 array[i] 小的时,就把后面的值 array[j] 赋给它
            if (i < j) {
                array[i] = array[j];
            }
            // 当队首元素小于等于基准数据 时,就一直向后挪动 i 指针
            while (i < j && array[i] <= key) {
                i++;
            }
            // 当找到比 array[j] 大的时,就把前面的值 array[i] 赋给它
            if (i < j) {
                array[j] = array[i];
            }
        }
        // 跳出循环时 i 和 j 相等,此时的 i 或 j 就是 key 的正确索引位置
        // 把基准数据赋给正确位置
        array[i] = key;
        return i;
    }
    
    void QuickSort(int array[], int low, int high) {
        // 开始默认基准为 low
        if (low < high) {
            // 分段位置下标
            int standard = getStandard(array, low, high);
            // 递归调用排序
            // 左边排序
            QuickSort(array, low, standard - 1);
            // 右边排序
            QuickSort(array, standard + 1, high);
        }
    }
    
    // 合并到一起快速排序
    // void QuickSort(int array[], int low, int high) {
    //     if (low < high) {
    //         int i   = low;
    //         int j   = high;
    //         int key = array[i];
    //         while (i < j) {
    //             while (i < j && array[j] >= key) {
    //                 j--;
    //             }
    //             if (i < j) {
    //                 array[i] = array[j];
    //             }
    //             while (i < j && array[i] <= key) {
    //                 i++;
    //             }
    //             if (i < j) {
    //                 array[j] = array[i];
    //             }
    //         }
    //         array[i] = key;
    //         QuickSort(array, low, i - 1);
    //         QuickSort(array, i + 1, high);
    //     }
    // }
    
    int main() {
        int array[] = {49, 38, 65, 97, 76, 13, 27, 49, 10};
        int size    = sizeof(array) / sizeof(int);
    
        // 打印数据
        printf("%d \n", size);
        QuickSort(array, 0, size - 1);
        display(array, size);
    
        // int size      = 20;
        // int array[20] = {0};                 // 数组初始化
        // for (int i = 0; i < 10; i++) {       // 数组个数
        //     for (int j = 0; j < size; j++) { // 数组大小
        //         array[j] = rand() % 1000;    // 随机生成数大小 0~999
        //     }
        //     printf("原来的数组:");
        //     display(array, size);
        //     QuickSort(array, 0, size - 1);
        //     printf("排序后数组:");
        //     display(array, size);
        //     printf("\n");
        // }
    
        return 0;
    }
    

    5. 结果展示

    (递归调用,不好展示每次排序结果)
    在这里插入图片描述

    6. 算法分析

    时间复杂度:

    1. 最好: O ( n l o g 2 n ) O(n log_{2} n) O(nlog2n)
    2. 最坏: O ( n 2 ) O(n^2) O(n2)
    3. 平均: O ( n l o g 2 n ) O(n log_{2} n) O(nlog2n)

    空间复杂度: O ( n l o g 2 n ) O(n log_{2} n) O(nlog2n)

    稳定性:不稳定

    展开全文
  • 快速排序例题

    2021-07-01 12:18:17
    快速排序例题 问题描述: 设一组初始记录关键字序列为(49,38,65,97,76,13,27,49),则以第一个关键字49为基准而得到一趟快速排序结果为: 姐:

    问题描述:
    设一组初始记录关键字序列为(49,38,65,97,76,13,27,49),则以第一个关键字49为基准而得到一趟快速排序结果为:

    姐:
    在这里插入图片描述

    展开全文
  • 完全不同于以前的排序算法,可以说,基数排序也叫做多关键字排序,基数排序是一种借助“多关键字排序”的思想来实现“单关键字排序”的内部排序算法。 两种方式: 1、最高位优先,先按照最高位排成若干子序列,再...
  • 快速排序

    2017-09-05 08:49:49
    其基本思想是:任取待排序序列中的某一个元素作为基准,通过一趟快速排序将待排序的元素分割成左右两个子序列,其中左子序列元素的排序关键字均比基准(也称枢轴)元素的关键字值小;右子序列元素的关键字均比基准元素...
  • 由于关键字的比较和交换是跳跃进行的,因此,快速排序是一种不稳定的排序方法。0. 序1. 冒泡排序2. 快速排序2.1基本思想2.2一趟快速排序(一趟划分)2.3过程2.4实现2.5复杂度分析2.5.1时间复杂度(包含证明)2.5.2空间...
  • 快速排序(三种算法实现和非递归实现)

    万次阅读 多人点赞 2017-11-29 18:41:44
    快速排序(Quick Sort)是对冒泡排序的一种改进,基本思想是选取一个记录作为枢轴,经过一趟排序,将整段序列分为两个部分,其中一部分的值都小于枢轴,另一部分都大于枢轴。然后继续对这两部分继续进行排序,从而使...
  • 直接插入排序,希尔排序,简单选择排序,冒泡排序,快速排序,堆排序,归并排序主要通过某种策略移动,选择或交换关键字来实现,关键字选择上,为了简便起见,都是整形数据。关键字间的比较,也都是直观的大小比较。...
  • 快速排序算法

    2021-01-11 13:37:49
    文章目录一、快速排序概述1.1 什么是快速排序1.2 快速排序过程解析二、快速排序的具体步骤三、快速排序的代码实现 一、快速排序概述 1.1 什么是快速排序 快速排序(Quick Sort)是对冒泡排序的一种改进。它的基本...
  • 序列排序

    2013-03-05 10:22:07
     对需要排序的数据元素序列,将其按关键字进行排序,若相同关键字元素之间的位置关系,排序前与排序后的相对位置不发生变化,称这种排序方法是稳定的,相反是不稳定的。 内部排序和外部排序:  内部排序是指待排...
  • 快速排序c++

    2021-03-30 09:10:02
    1、快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小。之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的。 2、快速排序的三个步骤: ...
  • 排序算法之快速排序

    2019-08-06 22:25:35
    设立一个关键字,其中一部分的所有数据都比关键字小,另外一部分的所有数据都比关键字大,然后再按此方法对这两部分数据分别进行快速排序,直到达到整个数据变成有序序列。 排序过程 快速排序的...
  • Java快速排序

    2021-06-08 15:06:43
    快速排序的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,已达到整个序列有序。一趟快速排序的具体过程可描述为...
  • 快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小。之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的。 2、快速排序的三个步骤: ...
  • 序列第K大数的部分快速排序

    千次阅读 2013-12-03 19:14:27
    用的是经典快速排序方法,每次快排都可以确定一个键的位置,得到关键字的下标,则可判断需要找的第K小的数在其左边还是右边,然后继续快排,直至找到恰好等于关键字为止。。   快速排序的基本思想是:每次从无序...
  • 快速排序C++

    2017-12-25 20:41:16
    快速排序讲解C++快速排序利用了分治的思想,分而治之。通过一趟排序将序列分为两部分,其中一部分比较关键字小,一部分比关键字大。之后继续对这两个子序列重复此过程,直到整个序列都有序。主要思路选基准值:在要...
  • 快速排序(Quick Sort)

    千次阅读 2019-09-27 16:45:14
    快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。 算法描述 快速排序使用分治法来把一个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 55,503
精华内容 22,201
关键字:

关键字序列快速排序