数据结构(2)

冒泡排序:

1.比较相邻的两个元素。如果前一个元素比后一个元素大,则交换两者位置。

2.对每一对相邻元素做相同工作,从第一对元素到最后一对元素,最后的一个元素就是最大的元素。

for(int i=a.length-1;i>0;i--){for (int j = 0; j <i; j++) {
if (greater(a[j],a[j+1])){
exch(a,j,j+1);
}
}
}

 时间复杂度为(n^2)

选择排序:

1.每次遍历过程中,都是假定第一个索引处的元素为最小值,和其他索引处的值依次进行比较,如果当前索引大于其他索引处的值,则认为这个索引为最小值,找出其索引

2.交换两个元素

for (int i=0;i<=a.length-2;i++){
//假定本次遍历,最小值所在的索引是i
int minIndex=i;
for (int j=i+1;j<a.length;j++){
if (greater(a[minIndex],a[j])){
//跟换最小值所在的索引
minIndex=j;
}
}
//交换i索引处和minIndex索引处的值
exch(a,i,minIndex);
}

 时间复杂度为O(n^2)

插入排序:

1.将所有元素分为两组,已排序和未排序。

2.把未排序中的第一个元素,向已排序中插入

3.倒叙遍历已排序的元素,依次和待插入的元素进行比较,直到找到一个元素小于等于待插入元素,那就将待插入元素放到这个位置,其余元素向后一位。

 

for (int i=1;i<a.length;i++){
//当前元素为a[i],依次和i前面的元素比较,找到一个小于等于a[i]的元素
for (int j=i;j>0;j--){
if (greater(a[j-1],a[j])){
//交换元素
exch(a,j-1,j);
}else {
//找到了该元素,结束
break;
}
}

 时间复杂度为O(n^2)

哈希排序:

1.选定一个增长量h,按照增长量作为分组的依据,对数据进行分组

2.对分好的每一组进行插入排序

3.减少增长量,直至为1,重复第二步

 

int N = a.length;
//确定增长量h的最大值
int h=1;
while(h<N/2){
h=h*2+1;
}
//当增长量h小于1,排序结束
while(h>=1){
//找到待插入的元素
for (int i=h;i<N;i++){
//a[i]就是待插入的元素
//把a[i]插入到a[i-h],a[i-2h],a[i-3h]...序列中
for (int j=i;j>=h;j-=h){
//a[j]就是待插入元素,依次和a[j-h],a[j-2h],a[j-3h]进行比较,如果a[j]小,那么
交换位置,如果不小于,a[j]大,则插入完成。
if (greater(a[j-h],a[j])){
exch(a,j,j-h);
}else{
break;
}
}
}
h/=2;
}

在处理大批量数据时,希尔排序的性能确实高于插入排序。

归并排序:

在方法内部调用方法本身就是递归。

1.尽可能将一组 数据拆分为两个元素相等的子组,并对每一个子组继续拆分,直到拆分后的每个子组的元素个数是1为止。将两个元素进行比较,放到辅助队列,将辅助队列进行替换原来的队列

2.将相邻的两个子组进行合并为一个有序的大组

3.重复步骤2,直到只有一个大组。

归并排序代码实现:
//排序代码
public class Merge {
private static Comparable[] assist;//归并所需要的辅助数组
/*
对数组a中的元素进行排序
*/
public static void sort(Comparable[] a) {
assist = new Comparable[a.length];
int lo = 0;
int hi = a.length-1;
sort(a, lo, hi);
}
/*
对数组a中从lo到hi的元素进行排序
*/
private static void sort(Comparable[] a, int lo, int hi) {
if (hi <= lo) {
return;
}
int mid = lo + (hi - lo) / 2;
//对lo到mid之间的元素进行排序;
sort(a, lo, mid);
//对mid+1到hi之间的元素进行排序;
sort(a, mid+1, hi);
//对lo到mid这组数据和mid到hi这组数据进行归并
merge(a, lo, mid, hi);
}
/*
对数组中,从lo到mid为一组,从mid+1到hi为一组,对这两组数据进行归并
*/
private static void merge(Comparable[] a, int lo, int mid, int hi) {
//lo到mid这组数据和mid+1到hi这组数据归并到辅助数组assist对应的索引处
int i = lo;//定义一个指针,指向assist数组中开始填充数据的索引
int p1 = lo;//定义一个指针,指向第一组数据的第一个元素
int p2 = mid + 1;//定义一个指针,指向第二组数据的第一个元素
//比较左边小组和右边小组中的元素大小,哪个小,就把哪个数据填充到assist数组中
while (p1 <= mid && p2 <= hi) {
if (less(a[p1], a[p2])) {
assist[i++] = a[p1++];
} else {
assist[i++] = a[p2++];
}
}
//上面的循环结束后,如果退出循环的条件是p1<=mid,则证明左边小组中的数据已经归并完毕,如果退
出循环的条件是p2<=hi,则证明右边小组的数据已经填充完毕;
//所以需要把未填充完毕的数据继续填充到assist中,//下面两个循环,只会执行其中的一个
while(p1<=mid){
assist[i++]=a[p1++];
}
while(p2<=hi){
assist[i++]=a[p2++];
}
//到现在为止,assist数组中,从lo到hi的元素是有序的,再把数据拷贝到a数组中对应的索引处
for (int index=lo;index<=hi;index++){
a[index]=assist[index];
}
}

缺点;需要申请额外的数组空间,空间复杂度上升,以空间换时间。

快速排序:

快速排序是对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

 1.初次设定第一个元素为分界值,从右向左找小于分界值的元素,从左往右找大于分界值的元素,替换两个元素,直到两个指针重叠。以此元素为分界值,通过分界值将数组分为两部分

2.大于等于分界值放到右边数组右边,小于等于放到左边

3.左右两边数据独立排序。对于左侧数组取一个分界值,分为两部分,左侧数据较小,右侧数据较大。右侧数据也是类似处理。

4.重复上述过程,递归处理。递归处理完左侧和右侧数据,排完序后,整个数组的排序就完成了。

 

public static void sort(Comparable[] a) {
int lo = 0;
int hi = a.length - 1;
sort(a, lo,hi);
}
private static void sort(Comparable[] a, int lo, int hi) {
if (hi<=lo){
return;
}
//对a数组中,从lo到hi的元素进行切分
int partition = partition(a, lo, hi);
//对左边分组中的元素进行排序
//对右边分组中的元素进行排序
sort(a,lo,partition-1);
sort(a,partition+1,hi);
}
public static int partition(Comparable[] a, int lo, int hi) {
Comparable key=a[lo];//把最左边的元素当做基准值
int left=lo;//定义一个左侧指针,初始指向最左边的元素
int right=hi+1;//定义一个右侧指针,初始指向左右侧的元素下一个位置
//进行切分
while(true){
//先从右往左扫描,找到一个比基准值小的元素
while(less(key,a[--right])){//循环停止,证明找到了一个比基准值小的元素
if (right==lo){
break;//已经扫描到最左边了,无需继续扫描
}
}
//再从左往右扫描,找一个比基准值大的元素
while(less(a[++left],key)){//循环停止,证明找到了一个比基准值大的元素
if (left==hi){
break;//已经扫描到了最右边了,无需继续扫描
}
}
if (left>=right){
//扫描完了所有元素,结束循环
break;
}else{
//交换left和right索引处的元素
exch(a,left,right);
}
}
//交换最后rigth索引处和基准值所在的索引处的值
exch(a,lo,right);
return right;//right就是切分的界限
}

归并排序将数组分成两个子数组分别排序,并将有序的子数组归并从而将整个数组排序。

快速排序的方式则是当两个数组都有序时,整个数组自然就有序了。

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

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

相关文章

VS2019+Qt5.15.2 编译 QtWebEngine(带音视频解码)

前言 QtWebEngine 是 Qt 框架的一部分&#xff0c;用于构建现代 Web 浏览器功能。本篇教程将向您展示如何在 Visual Studio 2019 中编译 QtWebEngine 5.15.2 源码&#xff0c;并配置以支持音视频解码功能。 准备工作 1、源码下载 2、源码修改&#xff0c;参考Qt Code Review…

微信小程序纯前端从阿里云OSS下载json数据-完整版

起因 因为云开发开始收费(貌似很久了),准备改造在以前的小程序,数据转到oss上,小程序使用原生,不算专业领域, 所以先百度.... 网上的教程真的是千篇一律,大部分开局就是require(ali-oss); 好点的npm install ali-oss --save开局,拼凑操作到最后发现要用云开发,因为云…

HTTPS代理搭建技巧分享

今天我们来分享一下如何搭建一个能够实现中间人 检测和防护的HTTPS代理。保护我们的网络通信安全是至关重要的&#xff0c;让我们一起学习如何构建一个安全可靠的HTTPS代理吧&#xff01; 什么是中间人 &#xff1f; 首先&#xff0c;让我们来了解一下什么是中间人 。中间人 是…

RK3399平台开发系列讲解(内核调试篇)内核中内存泄漏的调试

🚀返回专栏总目录 文章目录 一、Linux 内核内存泄漏二、如何观测内核内存泄漏?三、kmemleak 工具沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 内核内存泄漏往往都会是很严重的问题,那么,我们该如何判断内存泄漏是否是内核导致的呢? 一、Linux 内核内存泄漏 …

GPT-3.5——从 人工智障 到 大人工智障

有人说&#xff0c;GPT是从人工智障到人工智能的蜕变&#xff0c;但是。。。 我认为&#xff0c;GPT是从 人工智障 到 大人工智障 的退化。。。 从 人工智障 到 大人工智障 GPT-3.5学术介绍No.1---- 西红柿炒钢丝球基本信息详细制作方法材料步骤 幕后花絮 No.2---- 顶尖数学家…

【数据分析入门】Jupyter Notebook

目录 一、保存/加载二、适用多种编程语言三、编写代码与文本3.1 编辑单元格3.2 插入单元格3.3 运行单元格3.4 查看单元格 四、Widgets五、帮助 Jupyter Notebook是基于网页的用于交互计算的应用程序。其可被应用于全过程计算&#xff1a;开发、文档编写、运行代码和展示结果。 …

自动驾驶合成数据科普一:不做真实数据的“颠覆者”,做“杠杆”

前言&#xff1a; 在7月底的一篇文章中&#xff0c;九章智驾提到&#xff0c;数据闭环能力是自动驾驶下半场的“入场券”&#xff0c;这一观点在行业内引起了广泛共鸣。 在数据闭环体系中&#xff0c;仿真技术无疑是非常关键的一环。仿真的起点是数据&#xff0c;而数据又分为真…

基于MATLAB开发AUTOSAR软件应用层Code mapping专题-part 3 Paramter标签页介绍

这页是参数设置的界面,那首先要知道什么是参数,参数就是算法中的系数这些可以更改的变量,接下来就是要学习如何创建参数,如下图: 打开模型资源管理器 选择model Workspace标签,点击上边工具栏里的创建参数的按钮(红色箭头指向的按钮),添加一个新的参数K,值设置为4,数…

linux部署clickhouse(单机)

一、下载安装 1.1、下载地址 阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区阿里巴巴开源镜像站&#xff0c;免费提供Linux镜像下载服务&#xff0c;拥有Ubuntu、CentOS、Deepin、MongoDB、Apache、Maven、Composer等多种开源软件镜像源&#xff0c;此外还提供域名解析DNS、…

opencv进阶14-Harris角点检测-cv2.cornerHarris

类似于人的眼睛和大脑&#xff0c;OpenCV可以检测图像的主要特征并将这 些特征提取到所谓的图像描述符中。然后&#xff0c;可以将这些特征作为数据 库&#xff0c;支持基于图像的搜索。此外&#xff0c;我们可以使用关键点将图像拼接起 来&#xff0c;组成更大的图像。&#x…

软件开发bug问题跟踪与管理

一、Redmine 项目管理和缺陷跟踪工具 官网&#xff1a;https://www.redmine.org/ Redmine 是一个开源的、基于 Web 的项目管理和缺陷跟踪工具。它用日历和甘特图辅助项目及进度可视化显示&#xff0c;同时它又支持多项目管理。Redmine 是一个自由开源软件解决方案&#xff0c;…

通过DBeaver 给Postgre SQL表 设置主键自增

1.创建表 CREATE TABLE public.company ( id int4 NOT NULL , name text NOT NULL, age int4 NOT NULL, address bpchar(50) NULL, salary float4 NULL, join_date date NULL, CONSTRAINT company_pkey PRIMARY KEY (id) ); 2.插入数据&#xff08;不传入id&#xff…

机器学习:什么是分类/回归/聚类/降维/决策

目录 学习模式分为三大类&#xff1a;监督&#xff0c;无监督&#xff0c;强化学习 监督学习基本问题 分类问题 回归问题 无监督学习基本问题 聚类问题 降维问题 强化学习基本问题 决策问题 如何选择合适的算法 我们将涵盖目前「五大」最常见机器学习任务&#xff1a…

Android学习之路(7) Frament

Fragment 表示应用界面中可重复使用的一部分。fragment 定义和管理自己的布局&#xff0c;具有自己的生命周期&#xff0c;并且可以处理自己的输入事件。fragment 不能独立存在。它们必须由 activity 或其他 fragment 托管。fragment 的视图层次结构会成为宿主的视图层次结构的…

人事变动?前沃尔沃汽车大中华区总裁钦培吉将加盟吉利

根据消息&#xff0c;吉利控股集团高级副总裁杨学良在今天上午通过微博宣布&#xff0c;前沃尔沃汽车大中华区总裁钦培吉将加盟吉利。钦培吉将担任吉利汽车集团销售公司副总经理&#xff0c;并负责集团渠道发展委员会的主任一职&#xff0c;向吉利汽车集团的高级副总裁林杰报告…

0006Java程序设计-jsp婚恋交友网设计与实现

摘 要 在线交友是互联网发展的必然产物&#xff0c;它改变了人们的网络交往形态&#xff0c;使得人们的即时通信变得更加的直观和亲切&#xff0c;并且具有良好的发展趋势。 婚恋交友网站我们使用 Microsoft公司的JSP开发工具&#xff0c;利用其提供的各种面向对象的开发工具…

【C#学习笔记】委托和事件

文章目录 委托委托的定义委托实例化委托的调用多播委托 为什么使用委托&#xff1f;官方委托泛型方法和泛型委托 事件为什么要有事件&#xff1f;事件和委托的区别&#xff1a; 题外话——委托与观察者模式 委托 在 .NET 中委托提供后期绑定机制。 后期绑定意味着调用方在你所…

java面向对象——继承以及super关键字

继承的概念 1. 被继承的类称为父类&#xff08;超类&#xff09;&#xff0c;继承父类的类都称为子类&#xff08;派生类&#xff09; 2. 继承是指一个对象直接使用另一个对象的属性和方法&#xff0c;但是能继承非私有的属性和方法&#xff1b;(1) 构造方法不能被继承。(2) 但…

opencv进阶12-EigenFaces 人脸识别

EigenFaces 通常也被称为 特征脸&#xff0c;它使用主成分分析&#xff08;Principal Component Analysis&#xff0c;PCA&#xff09; 方法将高维的人脸数据处理为低维数据后&#xff08;降维&#xff09;&#xff0c;再进行数据分析和处理&#xff0c;获取识别结果。 基本原理…

pdf转word最简单方法~

pdf转word最简单方法&#xff01;pdf转word最简单方法我们都知道&#xff0c;PDF文件是一种只读文件格式&#xff0c;无法按照需求对PDF文件进行更改与编辑&#xff0c;从而影响到了PDF文件的使用。所以&#xff0c;我们需要将PDF文件转换为word文档&#xff0c;以此来保证文件…