数据结构学习(十三)、快速排序

基本思想:通过一趟排序将待排记录分割成独立两个部分,其中一部分记录的关键字均比另一部分记录的关键字小,

则可分别对这两部分继续进行排序,重复操作以上操作,已达到整个序列有序的目的

void QuickSort(SqList *L)
 {
    QSort(L,1,L->length);
 }
/* 对顺序表L中的子序列L->dara[low..high]最快速排序 */
 void QSort(SqList *L,int low,int high)
 {
    int pivot;
    if(low<high){
        pivot = Partition(L,low,high);        /*将L->data[low..high]一分为二,并算出分界点 */
        QSort(L,low,pivot-1);                  /* 分界点左边进行排序 */
        QSort(L,pivot+1,high);               /* 分界点右边进行排序 */
    }
 }
/*
交换L中子表的记录,使枢轴记录到位,并返回其所在的位置
此时,它之前(后)的记录均不大(小)于它
*/
 int Partition(SqList *L,int low,int high)
 {
    int pivotkey;
    pivotkey = L->r[low];
    while(low<high){
        while(low<high && L->r[high]>=pivotkey)
            high --;
        swap(L,low,high);
        while(low<high && L->r[low]<=pivotkey)
            low++;
        swap(L,low,high);
    }
    return low;
 }

改进算法:

1、优化选取枢轴

三数取中法,即先选取三个关键字进行排序,将中间数作为枢轴,一般取左端、中间、右端三个数。



/*
交换L中子表的记录,使枢轴记录到位,并返回其所在的位置
此时,它之前(后)的记录均不大(小)于它
*/
 int Partition(SqList *L,int low,int high)
 {
    int pivotkey;
    int m = low +(high-low)/2;            /* 计算数组中间元素的下标 */
    if(L->data[low]>L->data[high])      /* 交换左右保证左边的较小 */
         swap(L,low,high);
     if(L->data[m]>L->data[high])      /* 交换中间 和右边保证中间的较小 */
         swap(L,m,high);
     if(L->data[low]>L->data[m])      /* 交换中间 和左边保证左边的较小 */
         swap(L,m,low);
    pivotkey = L->data[m];                   /* 用子表的中间值作为枢轴 */
     L->data[0] = pivotkey;                     /* 将轴关键字备份到L->data[0] */
    while(low<high){
        while(low<high && L->data[high]>=pivotkey)
            high --;
        L->data[low] = L->data[high];        /* 采用替换 而不采用交换 */
        while(low<high && L->data[low]<=pivotkey)
            low++;
        L->data[high] = L->data[low];         /* 采用替换 而不采用交换 */
    }
    L->data[low] = L->data[0];                /* 将枢轴数值替换回L->data[low] */
    return low;
 }

 

优化不必要的交换

时间: 2024-10-29 03:04:54

数据结构学习(十三)、快速排序的相关文章

数据结构学习——堆

1 基本介绍 堆数据结构是一种数组对象,它可以被视为一颗完全二叉树.堆的访问可以通过三个函数来进行即, parent(i) return floor(i/2); left(i) return 2i; right(i) return 2i + 1; left操作可以通过一步左移操作完成,right操作可以通过左移并在地位+1实现,parent操作则可以通过把i右移一位得到.在实现中通常会使用宏或者内联函数来实现这三个操作. 二叉堆有两种,最大堆和最小堆.对于最大堆有 A[i] >= A[left(

小猪的数据结构学习笔记(四)

小猪的数据结构学习笔记(四) 线性表之静态链表 --转载请注明出处:coder-pig 本章引言: 在二,三中中我们分别学习了顺序表中的线性表与单链表,线性表有点类似于 我们前面所学的数组,而单链表使用的最多的是指针,这里问个简单的问题, 如果是在以前没有指针的话,前辈先人们怎么实现单链表呢?大家思考下! 没有指针,那么用什么来代替呢?前辈先人们非常机智,想出了使用下标+游标的方式 来实现单链表的效果!也就是今天要讲的--静态链表! 当然你也可以直接跳过本章,因为有了单链表就没有必要用静态链表了

小猪的数据结构学习笔记(二)

小猪的数据结构学习笔记(二) 线性表中的顺序表 本节引言: 在上个章节中,我们对数据结构与算法的相关概念进行了了解,知道数据结构的 逻辑结构与物理结构的区别,算法的特性以及设计要求;还学了如何去衡量一个算法 的好坏,以及时间复杂度的计算!在本节中我们将接触第一个数据结构--线性表; 而线性表有两种表现形式,分别是顺序表和链表;学好这一章很重要,是学习后面的基石; 这一节我们会重点学习下顺序表,在这里给大家一个忠告,学编程切忌眼高手低,看懂不代表自己 写得出来,给出的实现代码,自己要理解思路,自己

数据结构学习日记2:实现一个简单的线性表功能(链式存储方式)

数据结构学习日记,此次是用链表来实现一个线性表的功能 // ListTable1.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> using namespace std; #define ERROR 0; #define OK 1; typedef int Status; typedef int ElemType; //声明一个节点 typedef struct Node { ElemType d

数据结构学习之二叉排序树

介绍:二叉排序树是以一定的规则排列树中元素,因而可以进行快速的排序和查询的树状数据结构,一般规则是:对于树中任意一个节点,左孩子严格小于根,根严格小于右孩子,有点像大根堆.(只是大根堆中左右孩子关系并不确定,且和根的关系是统一的,而且有上浮和下沉操作使得大根堆总是一棵完全二叉树,其不断弹出堆顶形成有序列的过程叫做堆排序.虽然二叉排序树中也有旋转操作使得树尽量平衡,但是由于数值大小分明的左右孩子,在进行平衡操作时远不如大根堆方便快捷.)对于一棵已经构造完成的排序二叉树,它的中序遍历序列即为升序排列

文章分享:简单数据结构学习:单向链表

文章分享:简单数据结构学习:单向链表:https://www.textarea.com/aprikyb/jiandan-shujujiegou-xuexi-danxiang-lianbiao-252/

13. 蛤蟆的数据结构进阶十三排序实现之希尔排序法

13. 蛤蟆的数据结构进阶十三排序实现之希尔排序法 本篇名言:"一个人光溜溜的到这个世界来 ,最后光溜溜的离开这个世界而去 , 彻底想起来 , 名利都是身外物 ,只有尽一人的心力 , 使社会上的人多得他工作的裨益 ,是人生最愉快的事情.--邹韬奋" 下面是希尔排序法了. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47706135 1.  希尔排序 希尔排序(ShellSort)是插入排序的一种.也称缩小增量排序

数据结构学习系列之线性表(三)

前言数据结构学习,发现坚持下来比较难,本次学习与上次学习间隔了几个月,不管怎样还是要强迫自己坚持下来. 静态链表 用数组模拟链式结构的线性表,对于没有指针的编程语言,只能使用这种方式来模拟.这是大师们想出来的实现方法,体会大师们的编程思路,站在大师们的肩膀上解决一个又一个的难题.每个节点包含一个游标(数组数字索引),用于指向下个节点,所以静态链表也称为游标链表.规定数组第一个元素为备用链表(未被使用的数组游标,静态链表初始化时,会生成备用链表)的头节点,数组最后一个元素为链表的头节点.当需要插入

小猪的数据结构学习笔记(五)

小猪的数据结构学习笔记(五) 线性表之--循环链表                           --转载请注明出处:coder-pig 循环链表知识点归纳: 相关代码实现: ①判断是否为空表: ②单循环链表的存储结构 其实和单链表的结构是一样的! /*定义循环链表的存储结构*/ typedef struct Cir_List { int data; struct Cir_List *next; }Lnode; ③初始化循环单链表 代码如下: //1.循环链表的初始化 //表示一个元素,如