基础算法-排序(选择&冒泡&快排)

本文详细介绍了三种基础排序算法:选择排序、冒泡排序和快速排序。选择排序通过找到最小元素交换到已排序区间的末尾来实现;冒泡排序通过相邻元素比较交换实现排序;快速排序则是通过分区操作和递归实现高效排序。三种算法的时间复杂度分别为O(n^2)、O(n^2)和O(nlogn),其中快速排序在效率上更优,但稳定性较差。
摘要由CSDN通过智能技术生成

基础算法-排序(选择&冒泡&快排)

基本概念

选择排序

核心思路

选择排序和插入排序相似,也分已排序区间和未排序区间,选择排序每次会从未排序区间中找到最小元素,将其放到已排序区间的末尾,但是不想插入排序那样移动数组,选择排序会每次进行交换
4 5 6 3 2 1
第一次 1 5 6 3 2 4
第二次 1 2 6 3 5 4以此类推

代码实现
  package Sort;

import java.util.Arrays;

public class SelectSort {
	public static void main(String[] args) {
		int a[]={55,65,98,78,458,62,32,14,578,210,21};
		Slectsort(a);
		System.out.println(Arrays.toString (a));
	}
	//选择排序  
	public static void Slectsort(int a[]){
		for (int i=0;i<a.length-1;i++){
			int local=i;
			for (int j=i+1;j<a.length;j++){
				if (a[j]<a[local]){
					local=j;
				}
			}
			
			if(local!=i){
				swap(a,i,local);
			}
		}
	}
	//完成数组两元素间交换
	public static void swap(int[] arr,int a,int b){
		int temp = arr[a];
		arr[a] = arr[b];
		arr[b] = temp;
	}
}
分析

时间复杂度:O(n^2)
空间复杂度:O(n)
交换次数:n
稳定性:不稳定

冒泡排序

核心思路

冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换,一次冒泡会让至少一个元素移动到它应该在的位置,重复n次,就完成了n个数据的排序工作。
4 5 6 3 2 1
第一次冒泡结果:4 5 6 3 2 1=>4 5 3 6 2 1=>4 5 3 2 6 1=>4 5 3 2 1 6
第二次冒泡结果:4 5 3 2 1 6=>4 3 5 2 1 6=>4 3 2 5 1 6=>4 3 2 1 5 6
第三次冒泡结果:4 3 2 1 5 6=>3 4 2 1 5 6=>3 2 4 1 5 6=>3 2 1 4 5 6
第四次冒泡结果:3 2 1 4 5 6=>2 3 1 4 5 6=>2 1 3 4 5 6
第五次冒泡结果:2 1 3 4 5 6=>1 2 3 4 5 6

代码实现
package Sort;

import java.util.Arrays;

public class BubbleSort {
	public static void main(String[] args) {
		int data[]={4,5,6,3,2,1};
		bubbleSort(data);
		System.out.println(Arrays.toString(data));
	}
	public static void bubbleSort(int arr[]){  
		int n=arr.length;
		 
		for (int i=0;i<n-1;i++){            //冒泡排序的次数n-1
			boolean flag = true;            //加一个标记
			for (int j=0;j<n-1-i;j++){     //冒泡实现j=n-1-i是因为每冒泡一次都会确定一个数的位置
				if (arr[j]>arr[j+1]){      //当不执行此条if语句时,说明冒泡排序没有进行本身顺序就是排好的flag依然为true从下边if语句中跳出外层循环没必要再进行冒泡
					int temp=arr[j];
					arr[j]=arr[j+1];
					arr[j+1]=temp;
					flag =false;      
					/*
					 * arr[j]=arr[j]+arr[j+1];
					 * arr[j+1]=arr[j]-arr[j+1];
					 * arr[j]=arr[j]-arr[j+1];
					 */
				}
			}
			if (flag){            //if()括号里条件为true才会执行
				break;
			
			}
		}
		
	}

}

分析

时间复杂度:O(n^2)
空间复杂度:O(n)
交换次数:交换次数还是比较多的
稳定性:稳定

快速排序

核心思路

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 16 100 80
10 28 16 45 50 90 100 80
以基准数分为3部分,左边的比基准数小,右边的比基准数大
{10 28 16} 45 {50 90 100 80}
到此第一次以45位基准数的排序完成了

代码实现
package Sort;

import java.lang.reflect.Array;
import java.util.Arrays;

public class QuicklySort {
	public static void qSort(int data[],int left,int right){// left表示左边从哪开始,right表示右边在哪开始
		int base =data[left];     //去基准书为每段序列的第一个数
		int ll=left;  //表示从左边找的位置
		int rr=right; //表示从右边找的位置
		
		while (ll<rr){   //ll=rr时表示以某数为基准数的交换就找完了
			
			//第一步:从后边往前找比基准数小的数
			while (ll<rr && data[rr]>=base){   //data[rr]<base时跳出循环
				rr--;	
			}
			if (ll<rr){    //表示找到有比基准数小的数
				int temp=data[rr];
				data[rr]=data[ll];
				data[ll]=temp;
				ll++;             //此处ll++是每次交换完后下次比较时从下一个位置的数开始
			}
			//第二步:从前边往后找比基准数大的数
			while (ll<rr && data[ll]<=base){   //data[rr]>base时跳出循环
				ll++;
			}
			if (ll<rr){    //表示找到有比基准数大的数
				int temp=data[rr];
				data[rr]=data[ll];
				data[ll]=temp;
				rr--;
			}
		}
		
		//递归分成三部分,左右继续快排直到完成
		if(left<ll){	 //加上判断left和ll大小防止没找到,及基准数为最小的那个数
			qSort(data, left,ll-1);  //进行完一轮后分为三部分:ll=rr对应的是23行循环终止时ll和29行rr的值(即此次快排基准数的位置),
		}
		if (right>rr){   //加上判断right和rr大小防止没找到,及基准数为最大的那个数
			qSort(data, rr+1, right);
		}
	}
	public static void main(String[] args) {
		int a[]={45, 28, 80, 90, 50, 16, 100, 10};
		qSort(a, 0, a.length-1);
		System.out.println(Arrays.toString(a));
	}
}
分析

时间复杂度:O(nlogn)
空间复杂度:O(n)
稳定性:不稳定

图解

在这里插入图片描述

快排和归并的对比

1.归并排序处理过程是由下到上,先处理子问题,然后合并
2.快排是从上到下,先分区,再处理子问题不用合并

快排的优化就是优化基准数的选择

1.取三个数的中间

各种排序对比

对比

在这里插入图片描述

选择各种排序方法

1.分析场景:稳定还是不稳定
2.看数据量:数据量很小的时候有限选择插入排序,比如就50个100个数
3.分析空间
综上所述:没有一个固定的排序算法,都是根据场景需求分析,如果不会分析就用归并和快排

C++和java中的应用

C++中qSort中用的快排加插入排序
jdk里面的arrays.sort 一种是基础数据类型:int double 用的是快排, 对象排序:用的是归并+timeSort (timeSort是对归并的优化)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值