数据结构与算法-选择冒泡快排计数

    一:选择排序

    场景:找出一个班上身高最高的人你会怎么找?A B C D A B

选择排序的思路和插入排序非常相似,也分已排序和未排序区间。但选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。但是不像插入排序会移动数组 选择排序会每次进行交换,如以下例子:     

4 5 6 3 2 1

第一次:    1 5 6 3 2 4

第二次:    1 2 6 3 5 4

1.时间复杂度:O(N^2)

2.空间复杂度:O(n)

3.交换次数

4.稳定性:不稳定

   二:冒泡排序

        核心思路:冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复n次,就完成了n个数据的排序工作。

        举例说明:4 5 6 3 2 1,从小到大排序。 1 2 3 4 5 6

进行排序:什么样的情况下不做任何交换了呢,那就是所有的数都在它应该在的位置;O(n)

1.时间复杂度:O(n^2)

2.空间复杂度:O(n)

3.交换次数:挺大的

4.稳定性:稳定

package Sort2;import java.util.Arrays;/*** 冒泡排序*/public class BubbleSort {public static void main(String[] args) {int data[] = { 4, 5, 6, 3, 2, 1 };int n = data.length;//n-1:这里是因为判断两个数是只比较一次 例如: 1  2   比较次数只会比一次for (int i = 0; i < n - 1; i++) {	//排序的次数//优化:如果所有的数都排好了,不需要交换了,就不需要冒泡了,所以直接退出boolean flag = false;// n-1-i:要减掉i是因为每次冒泡排序都会将后面的值确定,所以i就是后面已经排好的数字,所以就不需要再比较了,所以得减掉for (int j = 0; j < n - 1 - i; j++) {	//具体冒泡 n - 1 - i,6,5,4,3,2,1if (data[j] > data[j + 1]) {//交换int temp = data[j];	//用了第三个变量,不用第三个变量data[j] = data[j + 1];data[j + 1] = temp;flag = true;//异或实现
//					data[j] = data[j] ^ data[j+1];
//					data[j+1] = data[j] ^ data[j+1];
//					data[j] = data[j] ^ data[j+1];}}if(!flag) break;}System.out.println(Arrays.toString(data));}
}
/*** 下面是交换的时候如果不用第三方变量存储的话如何交换*/
// a:2 b:3
// 3 2 => a:3 b:2
// 用加减
//a = a + b => a = 3+2 =5;
//b = a - b => b = 5-3 =2;
//a = a - b => a = 5-2 =3;
   2.1 如何进行简单的优化:

                1.  在交换的时候会需要第三方变量,会占空间,所以可以用异或交换。

                2. 当排好序了就不需要继续循环了,所以加flag作为标签。

       2.2 如何实现异或交换?

        异或操作可以实现交换两个数字的值的原因是因为异或操作具有以下几个性质:

  1. 任何数和0异或的结果仍然是这个数本身:a ^ 0 = a
  2. 任何数和自身异或的结果是0:a ^ a = 0
  3. 异或操作满足交换律:a ^ b = b ^ a 利用这些性质,我们可以通过异或操作实现交换两个数字的值,具体步骤如下: 假设有两个变量a和b,它们的初始值分别为a0和b0。
  4. 第一步:通过将a与b异或,将结果保存在a中:a = a ^ b。 此时,a的值为a0 ^ b0,b的值保持不变。
  5. 第二步:再将a与b异或,将结果保存在b中:b = a ^ b。 在这一步中,我们可以将上一步得到的a的值(a0 ^ b0)再与b0异或,得到的结果就是a0,即原始的a的值。 同时,由于异或操作满足交换律,所以b = (a0 ^ b0) ^ b0 = a0 ^ (b0 ^ b0) = a0 ^ 0 = a0。 此时,a的值保持不变,b的值变为a0。
  6. 第三步:最后将a与b异或,将结果保存在a中:a = a ^ b。 在这一步中,我们将上一步得到的a的值a0 ^ b0与上一步得到的b的值(a0)异或,得到的结果就是b0。
public class SwapNumbers {public static void main(String[] args) {int a = 10;int b = 20;System.out.println("交换前:");System.out.println("a = " + a);System.out.println("b = " + b);// 使用异或操作交换a和b的值a = a ^ b;b = a ^ b;a = a ^ b;System.out.println("交换后:");System.out.println("a = " + a);System.out.println("b = " + b);}
}

        三: 快速排序

45 28 80 90 50 16 100 10

基准数:一般就是取要排序序列的第一个。

第一次排序基准数:45

从后面往前找到比基准数小的数进行对换: 10 28 80 90 50 16 100 45

从前面往后面找比基准数大的进行对换: 10 28 45 90 50 16 100 80    

   10 28 16 90 50 45 100 80  

   10 28 16 45 50 90 100 80

以基准数分为3部分,左边的比之小,右边比之大:

{10 28 16} 45 {50 90 100 80}

到此第一次以45位基准数的排序完成。

1.时间复杂度:nlogn 最坏的情况就是O(n^2)

2.空间复杂度:O(n)

3.稳定性:不稳定

4.快排和归并的对比:

(1)归并排序的处理过程是由下到上的,先处理子问题,然后再合并。

(2)快排其实就是从上到下,先分区,在处理子问题,不用合并。 其优化就是优化基准数,提供一个取三个数中间的思路.

package Sort2;public class QuiklySort {public static void qSort(int data[], int left, int right) {int base = data[left]; // 就是我们的基准数,取序列的第一个,不能用data[0]int ll = left; // 表示的是从左边找的位置int rr = right; // 表示从右边开始找的位置while (ll < rr) {// 从后面往前找比基准数小的数while (ll < rr && data[rr] >= base) {rr--;}//这里有个小技巧,如果ll < rr为true,说明 data[rr] >= base = false,就找到比基准数小的,就要交换if (ll < rr) { // 表示是找到有比之大的int temp = data[rr];data[rr] = data[ll];data[ll] = temp;ll++;}// 从前面往后找比基准数大的数while (ll < rr && data[ll] <= base) {ll++;}if (ll < rr) {int temp = data[rr];data[rr] = data[ll];data[ll] = temp;rr--;}}// 肯定是递归 分成了三部分,左右继续快排,注意要加条件不然递归就栈溢出了//ll:循环终止时为基准数在最中间,然后将ll左右两部分继续递归if (left < ll)qSort(data, left, ll - 1);if (ll < right)qSort(data, ll + 1, right);}
}

        各种排序比较:

这么多种排序算法我们究竟应该怎么选择呢?

1.分析场景:稳定还是不稳定

2.数据量:数据量小的时候选什么?比如就50个数,优先选插入(5000*5000=25000000)

3.分析空间: 综上所述,没有一个固定的排序算法,都是要根据情况分析的。但是如果你不会分析的情况下 选择归并或者快排。

        四:计数排序

        如何对一个省200万学生的高考成绩(假设成绩最多只有2位小数,0~900范围)进行排序,用尽可能高效的算法。

package sorttest;import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;/*** 如何对一个省200万学生的高考成绩(假设成绩最多只有2位小数,0~900范围)进行排序,用尽可能高效的算法。*	计数排序*/public class CountSort {public static void main(String[] args) throws Exception {String str = null;String fileName = "D:\\JavaCode\\tulin\\src\\sorttest\\200w.txt";InputStreamReader isr = new InputStreamReader(new FileInputStream(fileName), "UTF-8");BufferedReader br = new BufferedReader(isr);int data[] = new int[2100002];int i = 0;//遍历所有的数据存到数组中while ((str = br.readLine()) != null) {double a = Double.valueOf(str);a = a * 100;data[i++] = (int) a;// System.out.println((int) a);}System.out.println("开始值为" + i);long start = System.currentTimeMillis();countSort(data, 0, data.length - 1);System.out.println("结束时间为" + (System.currentTimeMillis() - start) + "ms");}public static void countSort(int data[], int min, int max) throws Exception {int counts[] = new int[max + 1];//将所存的数字按照数组下标存储计数,for (int i = 0; i < data.length; i++) {counts[data[i]]++;}File file = new File("D:\\JavaCode\\tulin\\src\\sorttest\\200w-csort.txt");Writer out = new FileWriter(file);//同时从0开始遍历,所以也默认排好序,直接输出for (int i = 0; i <= max; i++) {if (counts[i] > 0) {for (int j = 0; j < counts[i]; j++) {out.write(((double) (i / 100.0)) + "\r\n");}}}out.close();}
}

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

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

相关文章

深度学习:循环神经网络RNN及LSTM

深度学习&#xff1a;循环神经网络RNN及LSTM 循环神经网络RNN原理代码 长短期记忆网络LSTM原理遗忘门记忆门输出门 代码 循环神经网络RNN 原理 对于传统的神经网络&#xff0c;它的信号流从输入层到输出层依次流过&#xff0c;同一层级的神经元之间&#xff0c;信号是不会相互…

Verilog零基础入门(边看边练与测试仿真)-时序逻辑-笔记(4-6讲)

文章目录 第四讲第五讲第六讲 第四讲 1、计数器 代码&#xff1a; //计数器 timescale 1ns/10ps module counter(clk,res,y); input clk; input res; output[7:0] y;reg[7:0] y; wire[7:0] sum;//1运算的结果&#xff08;1&#xff0…

Redis高效、安全的不停机数据迁移方案

Redis是目前最流行的键值对存储数据库&#xff0c;凭借高性能和丰富的数据类型的特性&#xff0c;不仅可以作为缓存&#xff0c;还可以作为一个可持久化的数据库存储。随着业务的发展和版本的迭代&#xff0c;必然会遇到内存不足、集群节点不够和BUG等一系列问题。为了防止这些…

ubuntu基本配置

记录一下每次重新安装系统之后都要进程的操作 更新源 更新源的教程 sudo bash -c "cat << EOF > /etc/apt/sources.list && apt update deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse deb-src http://mirrors.a…

1-4 AUTOSAR方法论

总目录——AUTOSAR入门详解AUTOSAR入门详解目录汇总&#xff1a;待续中。。。https://xianfan.blog.csdn.net/article/details/132818463 目录 一、前言 二、方法论 三、单个ECU开发流程 一、前言 汽车生产供应链上有以下角色&#xff1a;OEM、TIER1、TIER2&#xff0c;其主…

国内外大语言模型调研(更新到2023.09.12)

目录 国外 OpenAI-ChatGPT Anthropic-Claude Google-Bard 国内 百度-文心一言 清华大学&智谱AI-ChatGLM 百川智能-百川大模型 科大讯飞-星火 阿里-通义千问 360-360智脑 腾讯-混元大模型 华为-盘古大模型 字节跳动-云雀大模型 好未来-MathGPT 商汤科技-商量…

C基础-操作符详解

操作符分类&#xff1a; 算数操作符&#xff1a; - * / % //算数操作符 // int main() // { // // /除法 1.整数除法(除号两端都是整数) 2浮点数除法&#xff0c;除号的两端只要有一个小数就执行小数除法 // // 除法中&#xff0c;除数为0 // int a 7 / 2; /…

Java基础入门·多线程·线程池ThreadPool篇

前言 特点分析 线程池ThreadPool 销毁线程池 Executor类 ​​​​​​​ ​​​​​​​ ​​​​​​​ Callable接口 线程池使用 ​​​​​​​…

Android EditText setTranslationY导致输入法覆盖问题

平台 RK3288 Android 8.1 显示: 1920x1080 160 dpi 概述 碰到一个问题&#xff1a; 弹出的输入法会覆盖文本输入框。 原因&#xff1a;输入框使用了setTranslationY() 位置偏移后&#xff0c; 输入法无法正确获取焦点的位置。 分析 先上图: 初始布局 调用etTranslation…

抖音小程序开发教学系列(5)- 抖音小程序数据交互

第五章&#xff1a;抖音小程序数据交互 5.1 抖音小程序的网络请求5.1.1 抖音小程序的网络请求方式和API介绍5.1.2 抖音小程序的数据请求示例和错误处理方法 5.2 抖音小程序的数据缓存和本地存储5.2.1 抖音小程序的数据缓存机制和使用方法5.2.2 抖音小程序的本地存储和数据持久化…

unity 接收拼接数据进行纹理替换且保存相机纹理到rtsp server(一)

1 rtsp 协议后编码解码 rtsp协议的问题就是&#xff0c;拼接完成后&#xff0c;还需要编码&#xff0c;而unity里面再需要解码&#xff0c;需要的过程多了一步编码再解码&#xff0c;大大加重了 2 rtsp 协议后轻量编码 rtsp协议使用mjpeg进行图片传输。why&#xff1f;这样做…

vite + react + typescript + uni-app + node 开发一个生态系统

简介 使用 vite react typescript uni-app node 来开发一个简易的生态系统案例&#xff0c;包含 APP&#xff0c;H5&#xff0c;微信小程序&#xff0c;控制台&#xff0c;服务端 开发 admin 技术栈&#xff1a;vite react typescript初始化控制台项目选择自定义预设…

【C语言】指针的“最后一站”【进阶版】

欢迎各位看官^_^ 目录 1、字符指针 2、指针数组 3、数组指针 3.1数组指针的定义 3.2数组指针的使用 4、数组指针和指针数组的区别 5、数组参数&#xff0c;指针参数 5.1数组参数定义 5.2指针参数定义 5.3一维数组传参 5.4二维数组传参 5.5一级指针传参 5.6二级指…

《Docker 容器化的艺术:深入理解容器技术》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f405;&#x1f43e;猫头虎建议程序员必备技术栈一览表&#x1f4d6;&#xff1a; &#x1f6e0;️ 全栈技术 Full Stack: &#x1f4da…

javaweb04-vue基础

话不多说&#xff0c;参考官网地址Vue官网集成Vue应用。 一、Vue快速入门 &#xff08;1&#xff09;新建HTML页面&#xff0c;引入Vue.js 我这里用的是CDN方式 <script src"https://unpkg.com/vue3/dist/vue.global.js"></script> &#xff08;2&am…

windows10系统下Python3.11中安装Numpy库教程

Python3.11中安装Numpy库目录 项目场景&#xff1a;问题描述解决方案&#xff1a;①下载Numpy文件②把NumPy文件放到Python安装的Scripts文件夹里。③安装numpy④安装验证 项目场景&#xff1a; numpy是开源的数值计算扩展&#xff0c;用于数据分析、机器学习、科学计算的重要…

【Java 基础篇】Java TreeSet 详解:红黑树实现的有序集合

Java 集合框架提供了多种数据结构&#xff0c;用于存储和操作数据。其中&#xff0c;TreeSet 是一种特殊类型的集合&#xff0c;它通过红黑树&#xff08;Red-Black Tree&#xff09;数据结构实现了有序的、唯一元素存储。本篇博客将深入探讨 TreeSet&#xff0c;包括其概念、特…

小程序中使用分包

前言 小程序在未使用的分包的情况下仅支持大小为2M,如果图片等资源过多的情况下可以使用分包功能&#xff0c;使用分包的情况下单个分包大小不能超过2M,总大小不能超过20M&#xff0c;分包有两种情况&#xff1a;普通分包和独立分包&#xff0c;下面介绍的是普通分包。官方文档…

《向量数据库指南》——哪些需求推动了如Milvus Cloud等的向量数据库的更新和迭代?

这个问题需要深入讨论大模型与向量数据库之间的关系。从去年 ChatGPT 推出时这个问题就开始引发我们的思考。在当时,我们敏锐地意识到这将是一个机遇。然而,在国内,这个概念的认知需要更长的时间。我个人在去年四五月份的美国之行中注意到,数据库在美国已经是一个非常热门的…

算法通关村第十九关:青铜-动态规划是怎么回事

青铜挑战-动态规划是怎么回事 动态规划&#xff08;简称DP&#xff0c;Dynamic Programming&#xff09;&#xff1a;最热门、最重要的算法之一。面试中大量出现&#xff0c;整体偏难。 1. 热身&#xff1a;重复计算和记忆化搜索&#xff08;如何说一万次"我爱你"&…