数据结构算法——排序算法

news2024/11/8 5:31:10

1.排序

1.选择排序

不稳定,一般不用,基本排序

思路:过滤数组,找到最小数,放在前面。

不稳:导致原本在前的数据移动到后面。

	int arr[];
	for(i=0;i<arr.length-1;i++){
        int smallest=i;			
        for(j=i+1;j<length;j++){	
            if(arr[j]<arr[smallest]){
                smallest=j;
            }
         swap(arr,i,smallest);
        }
    }

时间复杂度O(n2),空间复杂度O(1)

2.冒泡排序

稳定,不常用,太慢,基本排序

思路:从第一个数两两比较,然后大的向后交换位置。

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

时间复杂度O(n2),空间复杂度O(1)

3.插入排序

稳定,三种基本排序中最常用,在数据较少且有一定次序时效率很高

思路:从第二位向后过滤,向前逐位比较并与更小的交换直到大于或等于。

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

时间复杂度O(n2),空间复杂度O(1)

4.希尔排序

稳定,是优化过的插入排序

思路:按一定数据间隔将数据分组进行插入排序,然后缩小间隔进行,直到为1。

问:为什么比插入排序更优?

答:分组大时,换位次数少。分组小时,换位距离短。

	int arr[];
	int h=1;
	while(h<=arr.length/3){
        h=h*3+1;			//计算Knuth数列
    }
	for(gap=h;gap>0;gap=(gap-1)/3){		//缩小间隔
		for(i=gap;i<arr.length;i++){
			for(j=i;j>gap-1;j-=gap){
				if(arr[j-gap]>arr[j]) swap(arr,j-gap,j);	//每组进行插入排序
			}
    	}

时间复杂度O(n^1.3),空间复杂度O(1)

5.归并排序

稳定,对于预先有一定次序的数组效率很高

思路:将数组递归地分为两部分,然后两个部分中的数依次比较,较小的填入中间数组。

public void sort(int[] arr,left,right){
	if(left==right) return;			//边界判定,何时停止
    int mid=left-(left+right)/2;		//递归中点计算
    sort(arr,left,mid);					//左侧递归
    sort(arr,mid+1,right);				//右侧递归
    merge(arr,left,mid,right);			//进行分组排序
    print(arr);
}	

public void merge(int[] arr,leftPtr,rightPtr,rightBound){
    int temp[]=new int[leftPtr-rightBound+1];		//定义中间数组
        
    int i=leftPtr;		//定义左指针,右指针
    int j=rightPtr;
    int k=-1;

    while(i<rightPtr&&j<rightBound){
        temp[k++] = arr[i] <= arr[j] ? arr[++i] : arr[++j];		//将左指针和右指针指向的数小的放入中间数组
    }	
        
    while(i<rightPtr-1) temp[k++]=arr[i++];		//将左侧剩余数放入中间数组
    while(j<rightBound) temp[k++]=arr[j++];			//将右侧剩余数放入中间数组
    
    for(int m=0;m<temp.length;m++) arr[leftPtr+m]=temp[m];			//将中间数组放入原数组
}

时间复杂度O(N log N),空间复杂度O(N)

6.快速排序

不稳

原理:选出一个数,将比它小的数放到它左侧,比它大的数放到它右侧。

可优化位双轴快速排序(java中对较大数组的排序方法)

/*
*@param left 左边界
*@param right 右边界
*/
public void sort(arr[],left,right){		
    //边界判断
    if(left>=right) return;		
    
    //初始化左右指针
    int i=left;						
    int j=right;
    //将最后一位定为pivot
    int pivot=arr[right];			

    while(i<j){
        //如果左侧比pivot大,则与右侧比pivot小的换位
        while(arr[i]<=pivot) i++;	
        while(arr[j]>pivot) j--;
        //如果左指针大于等于右指针说明本次排序结束
        if(i>=j) break;

        swap(arr,i,j);
        
    }
    if(arr[i]<=pivot){
        swap(arr,i+1,right);			//将pivot放在中间,此时,左侧比pivot小,右侧比pivot大
    }else{
        swap(arr,i,right);
    }
    
    sort(arr[],left,i-1);			//左侧递归
    sort(arr[],i,right);			//右侧递归
}

时间复杂度O(N log N),空间复杂度O(1)

7.计数排序

桶排序的一种,非比较排序,稳定(优化后),对于数量大但数据大小数量少的情况效率很高

思路:将每种数据的数量放入中间数组中,然后按放回原数组中。

	int arr[];
	//进行取数组最大值,最小值的步骤,在此处省略,并初始化min,max为最小最大值
	int max;
	int min;
	sort(arr,max,min){
        int count=new int[max-min+1];		//设置计数桶
        int temp[arr.length];				//初始化中间数组
        
        for(i=0;i<arr.length;i++){
            count[arr[i]-min]++;			//计数
        }
        
        for(j=0;j<count.length;j++){
            count[j+1]+=count[j];			//优化步骤,此时桶中存储的是该数据最后一位的位置
        }
        
        for(k=arr.length;k>=0;k--){
            temp[--count[ arr[k]-min ]] = arr[k];		//优化步骤,从原数组最后开始过滤,将数据放到对应位置
        }
        return temp;
    }

时间复杂度O(N+K),空间复杂度O(N+K)  (K是计数桶大小)

8.基数排序

桶排序的一种,非比较排序,基于技术排列,稳定

思路:对数据每一位上进行计数排列

从最低位开始的基数排序

	int arr[];
	//对最高位进行计算,此处跳过此步骤,直接初始化变量h为最高位数
	int h;
	
	sort(arr,h){
      
        int count=new int[10];		//设置计数桶,此时只有0-9
        int temp[arr.length];				//初始化中间数组
        
        for(m=0;m<h;m++){
            int divison=(int)Math.pow(10,m);		//求10的m次幂
            
        	for(i=0;i<arr.length;i++){
            	count[arr[i]/divison%10]++;			//计数
        		}
        
        	for(j=0;j<count.length-1;j++){			//优化步骤,此时桶中存储的是该数据最后一位的位置
            	count[j+1]+=count[j];			
        		}
        
        	for(k=arr.length;k>=0;k--){				//优化步骤,从原数组最后开始过滤,将数据放到对应位置
            	temp[--count[arr[k]]]=arr[k];		
        		}
        	}
        return temp;
    	}

从最高位开始的基数排序

递归思想

	int arr[];
	//对最高位进行计算,此处跳过此步骤,直接初始化变量h为最高位数
	int h;

	sort(arr,h){
        if(h=1) return temp;
       	int divison=(int)Math.pow(10,h);		//求10的i次幂
       	int count=new int[10];		//设置计数桶,此时只有0-9
       	int temp[arr.length];				//初始化中间数组
      	for(i=0;i<arr.length;i++){
            	count[arr[i]/divison%10]++;			//计数
        		}
        
        	for(j=0;j<count.length-1;j++){			//优化步骤,此时桶中存储的是该数据最后一位的位置
            	count[j+1]+=count[j];			
        		}
        	
        	sort(arr,h-1);
        
        	for(k=arr.length;k>=0;k--){				//优化步骤,从原数组最后开始过滤,将数据放到对应位置
            	temp[--count[arr[k]]]=arr[k];		
        		}
    }

时间复杂度O(N_K),空间复杂度O(N_K)  (K是计数桶大小)

9.桶排序

不常用,效率低

思路:将数据区域分为几个“桶”,将数据放入对应的“桶”中,对每个桶进行排序(其他排序方法或者递归)。

10.堆排序

堆排序是利用堆这种数据结构设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为 O(NlogN),不稳定

思路:将数组转换成一个堆(视情况使用大顶堆或者小顶堆,此处为大顶堆),将最大值下沉(第一位和最后一位换位),将其他位数转换成堆,直到数组有序。

public static void heapSort(int arr[]) {
    int temp = 0;
    for(int i = arr.length / 2 -1; i >=0; i--) {
        adjustHeap(arr, i, arr.length);
    }
    for(int j = arr.length-1;j >0; j--) {
        swap(i,j);
        adjustHeap(arr, 0, j);
    }
}

//将一个数组(二叉树), 调整成一个大顶堆
/**
* 功能: 完成 将 以 i 对应的非叶子结点的树调整成大顶堆
* @param arr 待调整的数组
* @param ptr 表示非叶子结点在数组中索引
* @param length 表示对多少个元素继续调整, length 是在逐渐的减少
*/
public static void adjustHeap(int arr[], int ptr, int length) {
    // k = ptr * 2 + 1 k 是 ptr 结点的左子结点
    for(int k = ptr * 2 + 1; k < length; k = k * 2 + 1) {
        //判断,避免遍历左右子树
        if(k+1 < length && arr[k] < arr[k+1]) { //如果左子节点比右子节点小,则转向右子节点
            k++; 									
        }
        //子节点判断
        if(arr[k] > arr[ptr]) { 	
            swap(arr,ptr,j) 	
                ptr = k; 				//对子树进行调整,避免结构混乱
        } else {
            break;
        }
    }
}

时间复杂度 O(N*Log N),空间复杂度O(1)

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

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

相关文章

计算机毕业设计 网上体育商城系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

加密

一、加密 加密运算需要两个输入&#xff1a;密钥和明文 解密运算也需要两个输入&#xff1a;密钥和密文 密文通常看起来都是晦涩难懂、毫无逻辑的&#xff0c;所以我们一般会通过传输或者存储密文来保护私密数据&#xff0c;当然&#xff0c;这建立在一个基础上&#xff0c;…

局域网windows下使用Git

windows下如何使用局域网进行git部署 准备工作第一步 &#xff0c;ip设置设置远程电脑的ip设置&#xff0c;如果不会设置请点击[这里](https://blog.csdn.net/Black_Friend/article/details/142170705?spm1001.2014.3001.5501)设置本地电脑的ip&#xff1a;验证 第二步&#x…

腾讯云使用

注&#xff1a;本文的所有演示的代码都基于尚硅谷的尚乐代驾项目 对象存储COS 一种云存储器 官方文档&#xff1a; 对象存储 快速入门-SDK 文档-文档中心-腾讯云 (tencent.com) 一 上传文件 1 初始化客户端 官方示例&#xff1a; // 1 传入获取到的临时密钥 (tmpSecret…

一文教你弄懂网络协议栈以及报文格式

文章目录 OSI七层网络协议栈示意图1. 应用层&#xff08;Application Layer&#xff09;2. 表示层&#xff08;Presentation Layer&#xff09;3. 会话层&#xff08;Session Layer&#xff09;4. 传输层&#xff08;Transport Layer&#xff09;5. 网络层&#xff08;Network …

Qt QSerialPort数据发送和接收DataComm

文章目录 Qt QSerialPort数据发送和接收DataComm2.添加 Qt Serial Port 模块3.实例源码 Qt QSerialPort数据发送和接收DataComm Qt 框架的Qt Serial Port 模块提供了访问串口的基本功能&#xff0c;包括串口通信参数配置和数据读写&#xff0c;使用 Qt Serial Port 模块就可以…

【超详细】Plaxis软件简介、 Plaxis Python API环境搭建、自动化建模、Python全自动实现、典型岩土工程案例实践应用

查看原文>>>【案例教程】PLAXIS软件丨自动化建模、典型岩土工程案例解析、模型应用、数据分析、图表制作 目录 第一部分&#xff1a;Plaxis软件简介及 Plaxis Python API环境搭建 第二部分&#xff1a;Plaxis自动化建模-基础案例 第三部分&#xff1a;进阶案例-Pyt…

C# HttpClient 实现HTTP Client 请求

为什么&#xff1f; C# httpclient get 请求和直接浏览器请求结果不一样 为了测试一下HTTP接口的&#xff0c;用C# HttpClient实现了HTTP客户端&#xff0c;用于从服务端获取数据。 但是遇到了问题&#xff1a;C# httpclient get 请求和直接浏览器请求结果不一样 初始代码如…

高德地图绘图,点标记,并计算中心点

效果图 代码如下 / 地图初始化 const map: any ref(null) const marker: any ref(null) const polyEditor: any ref(null) const view: any ref(false) const squareVertices: any ref([]) const init () > {workSpacesCurrent(workspaceId, {}).then((res) > {c…

html+css+js网页设计 旅游 龙门石窟8个页面

htmlcssjs网页设计 旅游 龙门石窟8个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#…

实战案例(5)防火墙通过跨三层MAC识别功能控制三层核心下面的终端

如果网关是在核心设备上面&#xff0c;还能用MAC地址进行控制吗&#xff1f; 办公区域的网段都在三层上面&#xff0c;防火墙还能基于MAC来控制吗&#xff1f; 采用正常配置模式的步骤与思路 &#xff08;1&#xff09;配置思路与上面一样 &#xff08;2&#xff09;与上面区…

分类预测|基于鲸鱼优化-卷积-门控制单元网络-注意力数据分类预测Matlab程序 WOA-CNN-GRU-Attention

分类预测|基于鲸鱼优化-卷积-门控制单元网络-注意力数据分类预测Matlab程序 WOA-CNN-GRU-Attention 文章目录 一、基本原理1. WOA&#xff08;鲸鱼优化算法&#xff09;2. CNN&#xff08;卷积神经网络&#xff09;3. GRU&#xff08;门控循环单元&#xff09;4. Attention&…

计算机毕业设计 基于SpringBoot的课程教学平台的设计与实现 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

IMS中的号码规整 5G注册流程中的语音相关参数

目录 1. IMS中的号码规整 1.1 主要内容 1.2 什么是 IMS 的号码规整及 FAQ 1.3 VoNR(VoLTE) 打 VoNR(VoLTE),被叫号码规整流程 主叫 AS 来做规整 主叫 S-CSCF 来做规整 2. 5G注册流程中的语音相关参数 2.1 主要内容 2.2 使用 VoNR 的第一步:5G注册流程 2.3 5G 注册流…

2024年9月12日(k8s环境及测试 常用命令)

一、环境准备及测试 1、报错处理&#xff1a; kube-system calico-node-5wvln 0/1 Init:0/3 0 16h kube-system calico-node-d7xfb 0/1 Init:0/3 0 16h ku…

3个WebSocket的.Net开源项目

推荐3个有关Websocket的.Net开源项目。 一、FreeIM 一个使用Websocket协议实现的、高性能即时聊天组件&#xff0c;可用于群聊、好友聊天、游戏直播等场景。 1、跨平台&#xff1a;基于.NetCore开发&#xff0c;支持Windows、Mono、Liunx、Windows Azure、Docker。 2、支持…

vue3使用panolens.js实现全景,带有上一个下一个,全屏功能

panolens官方文档Home - Panolens 1.加载核心js库 &#xff08;文件在untils里面&#xff09; import /utils/panolens/three.min.js; import /utils/panolens/panolens.min.js; /项目中 /railway/modalIframe/playPanorama/player/js/panolens-ht.js 为修改后版本 可以获取…

elementUI中el-form 嵌套el-from 如何进行表单校验?

在el-form中嵌套另一个el-form进行表单校验和添加规则&#xff0c;首先&#xff0c;需要确保每个嵌套的el-form都有自己的model、rules和ref。 以下是一个简化的示例&#xff1a; <template><el-form :model"parentForm" :rules"parentRules" r…

推荐7款可以写论文的AI免费工具,原创一键生成神器!

在当今学术研究和写作领域&#xff0c;AI技术的应用越来越广泛&#xff0c;特别是在论文写作方面。为了帮助学生和研究人员提高写作效率和质量&#xff0c;以下推荐7款可以写论文的AI免费工具&#xff0c;这些工具均具备一键生成高质量论文的功能&#xff0c;是原创写作的神器。…

工业机器人9公里远距离图传模块,无人机低延迟高清视界,跨过距离限制

在科技日新月异的今天&#xff0c;无线通信技术正以未有的速度发展&#xff0c;其中&#xff0c;图传模块作为连接现实与数字世界的桥梁&#xff0c;正逐步展现出其巨大的潜力和应用价值。今天&#xff0c;我们将聚焦一款引人注目的产品——飞睿智能9公里远距离图传模块&#x…