排序算法[Java]

本文深入讲解了快速排序、堆排序、归并排序、冒泡排序、插入排序、选择排序及基数排序等算法的原理与实现,包括算法的时间复杂度、稳定性分析及应用场景,适合初学者及进阶学习者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.快速排序
原理:通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则分别对这两部分继续进行排序,直到整个序列有序。
利用分治思想
平均时间O(nlogn) ,最坏 O(n2) ;
对于大的、乱序串列一般认为是最快的已知排序;
不稳定;
实现:三个while

public static int part(int [] arr,int low,int high) {
    	int key = arr[low];
    	while(low<high) {
    		while(low<high&&arr[high]>=key)
    			high--;
    		arr[low] = arr[high];
    		while(low<high&&arr[low]<=key)
    			low++;
    		arr[high]=arr[low];
    	}
    	arr[low] = key;
    	return low;
    }
    public static void quicksort(int[] array,int lo ,int hi){
    	if(lo<hi) {
        int index=partition(array,lo,hi);
        sort(array,lo,index-1);
        sort(array,index+1,hi); 
    	}
    }

2.堆排序
原理:堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
O(nlogn);
不稳定;
堆排序的时间复杂度,主要在初始化堆过程和每次选取最大数后重新建堆的过程;
初始化建堆过程时间:O(n)
更改堆元素后重建堆时间:O(nlogn)
堆排序每次只对一个元素操作,是就地排序,所用辅助空间O(1)。

public static void adjust(int [] arr,int i,int length) {
		int tmp=arr[i];
		for(int k=i*2+1;k<length;k=k*2+1) {
			if(k+1<length&&arr[k+1]>arr[k])
				k=k+1;
			if(arr[k]>tmp) {
				arr[i]=arr[k];
				i=k;
			}else
				break;
		}
		arr[i]=tmp;
	}
	public static void heapsort(int [] arr) {
		for(int i=arr.length/2-1;i>=0;i--)
			adjust(arr,i,arr.length);
		
		for(int j=arr.length-1;j>0;j--) {
			swap(arr,0,j);
			adjust(arr,0,j);
		}
	}
public static void swap(int [] arr,int left,int right) {
		int tmp=arr[left];
		arr[left]=arr[right];
		arr[right]=tmp;
	}

3.归并排序
O(nlogn); 需要 O(n) 额外存储空间;
稳定;
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
递归终止条件(每段只有一个元素,默认有序);
优点:归并排序只对相邻的数组元素进行处理,所以相对来说归并排序的速度有可能在某一数据量区域内优于普通快排;
缺点:归并排序占用了大量的内存空间(占用了和原数组等长的空间,一旦待排数组的量非常巨大的话,这完全是致命的缺点)里进行排序操作,所以来说,归并排序在大数据的时候很容易造成内存的溢出;

	public static void merge(int[] arr, int low, int mid, int high) {
		int[] temp = new int[high - low + 1];
		int i = low;
		int j = mid + 1;
		int k = 0;
		while (i <= mid && j <= high) {
			if (arr[i] < arr[j])
				temp[k++] = arr[i++];
			else
				temp[k++] = arr[j++];
		}
		while (i <= mid)
			temp[k++] = arr[i++];
		while (j <= high)
			temp[k++] = arr[j++];
		for (int a = 0; a < temp.length; a++) {
			arr[a + low] = temp[a];
		}
	}
		public static void mergesort(int[] arr, int low, int high) {
		int mid = (low + high) / 2;
		if (low < high) {
			mergesort(arr, low, mid);
			mergesort(arr, mid + 1, high);
			merge(arr, low, mid, high);
		}
	}

4.冒泡排序
原理:比较两个相邻的元素,将值大的元素交换至右端。
O(n2)最好n
稳定
外层控制迭代次数,内层控制比较次数

public static void bubbleSort(int[] arr)
    {
		int len = arr.length;
		for(int i=0;i<len-1;i++) {
			for(int j=0;j<len-i-1;j++) {
				if(arr[j]>arr[j+1]) {
					int tmp = arr[j];
					arr[j]=arr[j+1];
					arr[j+1]=tmp;
				}
			}
		}
	}

5.插入排序
思想:插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
最好n,最坏n2
平均O(n2);
稳定;

	public static void insertsort(int[] arr) {
		int len = arr.length;
		int temp, j;
		for (int i = 0; i < len; i++) {
			temp = arr[i];
			for (j = i; j > 0 && temp < arr[j - 1]; j--) {
				arr[j] = arr[j - 1];
			}
			arr[j] = temp;
		}
	}

6.选择排序
思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。
O(n2);
不稳定;

	public static void selectsort(int[] arr) {
		int len = arr.length;
		int temp;
		for(int i=0;i<len;i++) {
			int k=i;
			for(int j=len-1;j>i;j--) {
				if(arr[j]<arr[k])
					k=j;
			}
			temp = arr[i];
			arr[i]=arr[k];
			arr[k]=temp;
		}
	}

7.基数排序

8.希尔排序
不稳定
平均n2,最好n,最坏n2
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值