08_排序

基本概念与分类

假设含有n个记录的序列为 { r 1 , r 2 , . . . , r n } \{r_1,r_2,...,r_n\} {r1,r2,...,rn},其相应的关键字分别为 { k 1 , k 2 , . . . , k n } \{k_1,k_2,...,k_n\} {k1,k2,...,kn},需确定1,2,…,n的一种排列 p 1 , p 2 , . . . , p n p_1,p_2,...,p_n p1,p2,...,pn,使其相应的关键字满足 k p 1 ≤ k p 2 ≤ . . . ≤ k p n k_{p1}\leq k_{p2}\leq ... \leq k_{pn} kp1kp2...kpn(非递减或递增)关系,即使得序列成为一个按关键字有序的序列 { r p 1 , r p 2 , . . . , r p n } \{r_{p1},r_{p2},...,r_{pn}\} {rp1,rp2,...,rpn},这样的操作称为排序。

排序的稳定性

假设 r i = r j ( 1 ≤ i ≤ n , i ≤ j ≤ n , i ≠ j ) r_i=r_j(1 \leq i \leq n,i \leq j \leq n,i \neq j) ri=rj(1in,ijn,i=j),且在排序前的序列中 r i r_i ri领先与 r j r_j rj。如果排序后 r i r_i ri仍然领先与 r j r_j rj,则称所用的排序方法是稳定的;反之则是不稳定的。

内排序与外排序

内排序是在排序整个过程中,待排序的所有记录全部被就置在内存中 。外排序是由于排序的记录个数太多 , 不能同时放置在内存,整个排序过程需要在内外存之间多次交换数据才能进行。

排序用到的结构与函数

#define MAXSIZE 10    /* 用于要排序数组个数最大值,可以根据需要修改 */
typedef struct
{int r[MAXSIZE+1]; /* 存储要排序的数组,r[0]用作哨兵或临时变量 */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;
}

冒泡排序

冒泡排序(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]){swap(L,i,j);}}}
}
/* 对顺序表L作交换排序(冒泡排序改进版) */
void BubbleSort(SqList *L)
{int i,j;for(i=1;i<L->length;i++){for(j=L->length-1;j>=i;j--) /* 注意j是从后向前循环 */{if(L->r[j]>L->r[j+1])   /* 若前者大于后者(注意这里与上一算法的差异) */{swap(L,j,j+1);}}}
}
/* 对顺序表L作交换排序(冒泡排序优化版) */
void BubbleSort2(SqList *L)
{int i,j;bool flag = true;				/* flag用来作为标记 */for(i=1;i<L->length && flag ;i++) /* flag为false,则退出循环 */{flag = false;				/* 初始化false */for(j=L->length-1;j>=i;j--) {if(L->r[j]>L->r[j+1])   {swap(L,j,j+1);flag = true; /* 如果有数据交换,则flag为true */}}}
}

冒泡排序算法的时间复杂度:KaTeX parse error: Expected group after '_' at position 5: \sum_̲\limits{i=2}^{n…,总的时间复杂度为 O ( n 2 ) O(n^2) O(n2)

简单选择排序

简单选择排序法(Simple Selection Sort)就是通过 n − i n-i ni 次关键字间的比较,从 n − i + 1 n-i+1 ni+1 记录中选出关键字最小的记录,并和第 i ( 1 ≤ i ≤ n ) i(1\leq i \leq n) i(1in) 个记录交换。

/* 对顺序表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 = j;   			   /* 将此关键字的下标赋值给min */}if(i != min)				   /* 若min不等于i,说明找到最小值,交换 */swap(L,i,min)			   /* 交换L->r[i]与L->r[min]的值 */}
}

简单选择排序算法的时间复杂度:KaTeX parse error: Expected group after '_' at position 5: \sum_̲\limits{i=1}^{n…,总的时间复杂度为 O ( n 2 ) O(n^2) O(n2)

尽管与冒泡排序同为 O ( n 2 ) O(n^2) O(n2),但简单选择排序的性能上还是略优于冒泡排序。

直接插入排序

直接插入排序(Straight Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增加1的有序表。

/* 对顺序表L作直接插入排序 */
void InsertSort(SqList * L) {int i,j;for(i=2;i<L->length;i++){if(L->r[i] < L->r[i-1]){ /* 需将L->r[i]插入有序子表 */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];     /* 插入到正确位置 */}}
}

最好情况(有序表本身有序)下的算法复杂度: n − 1 ( ∑ i = 2 n 1 ) n-1(\sum_{i=2}^n1) n1(i=2n1) ,时间复杂度为O(n)

最坏情况(有序表是逆序)下的算法复杂度:比较 KaTeX parse error: Expected group after '_' at position 5: \sum_̲\limits{(i=2)}^…次,记录移动KaTeX parse error: Expected group after '_' at position 5: \sum_̲\limits{i=2}^{n…

如果排序记录是随机的,那么根据概率相同的原则,平均比较和移动次数约为 n 2 4 \frac{n^2}4 4n2。直接插入排序法的时间复杂度为 O ( n 2 ) O(n^2) O(n2) ,直接插入排序法比冒炮和简单选择排序的性能要好一些。

希尔排序算法

  1. 将原本有大量记录数的记录进行分组,分割成若干个子序列。

  2. 在这些子序列内进行插入排序,当整个序列基本有序时,再对全体记录进行一次直接插入排序

    所谓的基本有序,就是小的关键字基本在前面,大的基本在后面,不大不小的基本在中间。

/* 对顺序表L作希尔排序 */
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[i]; /* 暂存在L->r[0] */for(j=i-increment;j>0 && L->r[0]< L->r[j];j-=increment)L->r[j+increment] = L->r[j]; /* 记录后移,查找插入位置 */L->r[j+increment] = L->r[0]; /* 插入 */}}        }while(increment > 1);
}

希尔排序的关键并不是随便分组后各自排序,而是将相隔某个"增最’'的记录组成一个子序列, 实现跳跃式的移动,使得排序的效率提高 。

这里"增量"的选取就非常关键,当增量序列为 d l t a [ k ] = 2 t − k + 1 − 1 ( 0 ≤ k ≤ t ≤ [ l o g 2 ( n + 1 ) ] ) dlta[k] = 2^{t-k+1}-1 (0\leq k \leq t \leq [log_2(n+1)]) dlta[k]=2tk+11(0kt[log2(n+1)]) 时,可以获得不错的效率。

希尔排序并不是一直稳定排序,时间复杂度为 O ( n 3 / 2 ) O(n^{3/2}) O(n3/2)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/40906.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务: Nacos部署安装与properties配置

Nacos 是阿里巴巴开源的一款用于动态服务发现、配置管理和服务管理的基础设施。Nacos 这个名称源自于 “Dynamic Naming and Configuration Service”。它主要是用于解决微服务架构中服务发现和配置管理的问题。 Nacos 单机模式的部署安装 1. 安装(Windows环境) Nacos是Java…

Java线程基础知识总结

基础概念 Java 线程是并发编程的基础&#xff0c;涉及到线程的创建、管理、同步以及通信。理解和掌握线程的使用对于编写高效和响应快速的应用程序至关重要。 1. 线程基础 线程是程序中的执行流。每个Java程序至少有一个线程 — 主线程&#xff08;main&#xff09;。通过使…

从入门到深入,Docker新手学习教程

编译整理&#xff5c;TesterHome社区 作者&#xff5c;Ishaan Gupta 以下为作者观点&#xff1a; Docker 彻底改变了我们开发、交付和运行应用程序的方式。它使开发人员能够将应用程序打包到容器中 - 标准化的可执行组件&#xff0c;将应用程序源代码与在任何环境中运行该代码…

InspireFace-商用级的跨平台开源人脸分析SDK

InspireFace-商用级的跨平台开源人脸分析SDK InspireFaceSDK是由insightface开发的⼀款⼈脸识别软件开发⼯具包&#xff08;SDK&#xff09;。它提供了⼀系列功能&#xff0c;可以满⾜各种应⽤场景下的⼈脸识别需求&#xff0c;包括但不限于闸机、⼈脸⻔禁、⼈脸验证等。 该S…

ubuntu22 sshd设置

专栏总目录 一、安装sshd服务 sudo apt updatesudo apt install -y openssh-server 二、配置sshd 使用文本编辑器打开/etc/ssh/sshd_config sudo vi /etc/ssh/sshd_config &#xff08;一&#xff09;配置sshd服务的侦听端口 建议将ssh的侦听端口改为7000以上的端口&#…

【bazel】快速下载教程

bazel下载链接&#xff1a; https://github.com/bazelbuild/bazel/releases?page11 直接在github上下载&#xff0c;会因为网络不稳定&#xff0c;而频繁下载错误 这里提供一个超级快速的方法&#xff01;&#xff01;&#xff01; 用迅雷下载&#xff01; 1.从github上复…

cpp http server/client

httplib 使用httplib库 basedemo server.cpp #include "httplib.h" #include <iostream> using namespace httplib;int main(void) {Server svr;svr.Get("/hello", [](const Request& req, Response& res) {std::cout << "lo…

实现Java Web应用的高性能负载均衡方案

实现Java Web应用的高性能负载均衡方案 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在高并发的网络环境中&#xff0c;负载均衡是确保Web应用程序高性能和可靠性的关键策略之一。本文将探讨如何…

【力扣 - 每日一题】3115. 质数的最大距离(一次遍历、头尾遍历、空间换时间、埃式筛、欧拉筛、打表)Golang实现

原题链接 题目描述 给你一个整数数组 nums。 返回两个&#xff08;不一定不同的&#xff09;质数在 nums 中 下标 的 最大距离。 示例 1&#xff1a; 输入&#xff1a; nums [4,2,9,5,3] 输出&#xff1a; 3 解释&#xff1a; nums[1]、nums[3] 和 nums[4] 是质数。因此答…

算法系列--分治排序|再谈快速排序|快速排序的优化|快速选择算法

前言:本文就前期学习快速排序算法的一些疑惑点进行详细解答,并且给出基础快速排序算法的优化版本 一.再谈快速排序 快速排序算法的核心是分治思想,分治策略分为以下三步: 分解:将原问题分解为若干相似,规模较小的子问题解决:如果子问题规模较小,直接解决;否则递归解决子问题合…

策略模式的应用

前言 系统有一个需求就是采购员审批注册供应商的信息时&#xff0c;会生成一个供应商的账号&#xff0c;此时需要发送供应商的账号信息&#xff08;账号、密码&#xff09;到注册填写的邮箱中&#xff0c;通知供应商账号信息&#xff0c;当时很快就写好了一个工具类&#xff0…

Python 学习中什么是字典,如何操作字典?

什么是字典 字典&#xff08;Dictionary&#xff09;是Python中的一种内置数据结构&#xff0c;用于存储键值对&#xff08;key-value pair&#xff09;。字典的特点是通过键来快速查找值&#xff0c;键必须是唯一的&#xff0c;而值可以是任何数据类型。字典在其他编程语言中…

vue实现搜索文章关键字,滑到指定位置并且高亮

1、输入搜索条件&#xff0c;点击搜索按钮 2、滑到定位到指定的搜索条件。 <template><div><div class"search_form"><el-inputv-model"searchVal"placeholder"请输入关键字查询"clearablesize"small"style&quo…

HashMap的底层实现原理详解

HashMap是Java中最常用的集合类之一&#xff0c;其基于哈希表的Map接口实现&#xff0c;提供了快速的键值对存储和检索功能。深入理解HashMap的底层实现原理&#xff0c;对于提升编程技能、应对技术面试以及优化程序性能都具有重要意义。以下从技术难点、面试官关注点、回答吸引…

数据库作业day3

创建一个student表用于存储学生信息 CREATE TABLE student( id INT PRIMARY KEY, name VARCHAR(20) NOT NULL, grade FLOAT ); 向student表中添加一条新记录 记录中id字段的值为1&#xff0c;name字段的值为"monkey"&#xff0c;grade字段的值为98.5 insert into …

对于老百姓而言VR到底能做什么?

VR技术自诞生以来不断发展&#xff0c;已经广泛应用于教育、医疗、工程、军事、航空、航海、影视、娱乐等方面&#xff0c;譬如&#xff0c;大型工程或军事活动VR预演可以大幅度减少人力物力投入&#xff1b;在航空领域&#xff0c;航天飞行员在训练舱中面对屏幕进行各种驾驶操…

mysql修改密码失败报错无法登录解决办法

mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user root@localhost (using password: YES) 这个问题是因为在尝试使用命令行连接MySQL时,使用了明文密码,这是不安全的。同时,由于某种原因,您…

Kylin中的查询引擎:大数据查询加速的引擎解析

Kylin中的查询引擎&#xff1a;大数据查询加速的引擎解析 Apache Kylin是一个开源的分布式分析引擎&#xff0c;专为大规模数据集提供快速的SQL查询和多维分析&#xff08;OLAP&#xff09;能力。在Kylin的架构中&#xff0c;查询引擎&#xff08;Query Engine&#xff09;扮演…

【Linux进阶】文件系统4——文件系统特性

1.磁盘组成与分区的复习 首先说明一下磁盘的物理组成&#xff0c;整块磁盘的组成主要有&#xff1a; 圆形的碟片&#xff08;主要记录数据的部分&#xff09;&#xff1b;机械手臂&#xff0c;与在机械手臂上的磁头&#xff08;可擦写碟片上的数据);主轴马达&#xff0c;可以…

打开浏览器控制台,点击应用,浏览器崩溃

调试的时候&#xff0c;打开控制台&#xff0c;点击 “应用” 立马浏览器奔溃&#xff0c;但是点击别的没问题 调查发现是因为manifest.json这个文件引起的 manifest.json 最主要的原因是因为没有设置这个sizes字段 Google浏览器更新大概到126之后的版本会有问题&#xff0c;之…