1、冒泡排序:
* i和i+1位置的数比较,如果nums[i]>nums[i+1],就交换
* 第一趟:i从0~N,i和i+1依次比较交换,最大值会出现在最后位置
* 第二趟:i从0~N-1,i和i+1依次比较交换,最大值会出现在倒数第二个位置
* ......
* 经过第N-1趟比较,最后的得到排好序的数组
*
* 时间复杂度为O(N^2)
* 稳定排序
public class BubbleSort {
public static void main(String[] args) {
int[] nums = new int[]{1,3,2,7,4,2};
bubbleSort(nums);
for (int num: nums) {
System.out.print(num);
}
}
public static void bubbleSort(int[] nums){
int isChange;//如果isChange == 0,这一趟没有进行交换,说明已经排好序了
//外层循环控制需要排序的趟数
for(int i=0; i<nums.length-1; i++){
isChange = 0;
for(int j=0; j<nums.length-i-1; j++){
if(nums[j] > nums[j+1]){
swap(nums, j, j+1);
isChange = 1;
}
}
if(isChange == 0){
break;
}
}
}
public static void swap(int[] nums, int i, int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
2、选择排序
选择排序:每一趟比较中都选出最大值,记录该最大值的位置,与最后一个元素交换
*
* 时间复杂度O(N^2)
* 不稳定排序
public class SelectSort {
public static void main(String[] args) {
int[] nums = new int[]{1,3,2,7,4,2};
selectSort(nums);
for (int num: nums) {
System.out.print(num+" ");
}
}
public static void selectSort(int[] nums){
int max;//最大值
int pos;//最大值位置
//外层循环控制排序的趟数,因为排序到最后,第一个元素就不需要交换了,所以i到nums.length-1;
for(int i=0; i<nums.length-1; i++){
max = nums[0];
pos = 0;
//每一趟比较,将第0个元素作为初始最大值,从第一个位置开始,直到最后一个元素寻找最大值
for(int j=1; j<nums.length-i;j++){
if(nums[j] > max){
max = nums[j];
pos = j;
}
}
swap(nums, pos, nums.length-i-1);
}
}
public static void swap(int[] nums, int i, int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
3、插入排序
*插入排序:每次将当前元素插入到前面已经排好序的数组中
*
* 时间复杂度O(N^2):小样本情况下,排序很快,因为常数项很低
* 稳定排序
public class InsertSort {
public static void main(String[] args) {
int[] nums = new int[]{1,3,2,7,4,2};
selectSort(nums);
for (int num: nums) {
System.out.print(num+" ");
}
}
public static void selectSort(int[] nums){
for(int i=0; i<nums.length; i++){
int j=i;
while(j>0 && nums[j]<nums[j-1]){
swap(nums, j, j-1);
j--;
}
}
}
public static void swap(int[] nums, int i, int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
4、归并排序
*归并排序:先分后合
* 时间复杂度O(NlogN)
* 稳定排序
public class MergeSort {
public static void main(String[] args) {
int[] nums = new int[]{1,3,2,7,4,2};
mergeSort(nums,0, nums.length-1);
for (int i=0; i<nums.length; i++) {
System.out.print(nums[i]+" ");
}
}
public static void mergeSort(int[] nums, int start, int end){
if(start < end){
int mid = (start+end)/2;
mergeSort(nums, start, mid);
mergeSort(nums, mid+1, end);
merge(nums, start, mid+1, end);
}
}
public static void merge(int[] nums, int start, int mid, int end){
int i=start;
int j=mid;
int k=0;
int[] help = new int[end-start+1];
while (i < mid && j <=end){
if(nums[i] < nums[j]){
help[k++] = nums[i++];
}else{
help[k++] = nums[j++];
}
}
while(i < mid){
help[k++] = nums[i++];
}
while(j <= end){
help[k++] = nums[j++];
}
for(int t=0; t<help.length; t++){
nums[start++] = help[t];
}
}
}
5、快排
import java.util.Arrays;
public class QuickSort {
public static void main(String[] args) {
int[] arrays = new int[]{3,543,542,45,78,8};
quickSort(arrays, 0, arrays.length-1);
System.out.println(Arrays.toString(arrays));
}
public static void quickSort(int[] arrays, int l, int r){
if(l<r){
int[] qujian = partition(arrays, l, r);
quickSort(arrays, l, qujian[0]-1);
quickSort(arrays, qujian[1]+1, r);
}
}
private static int[] partition(int[] arrays, int l, int r) {
int less = l-1;
int more = r;
while(l < more){
if(arrays[l] <arrays[r]){
swap(arrays, ++less, l++);
}else if(arrays[l] > arrays[r]){
swap(arrays, l, --more);
}else{
l++;
}
}
swap(arrays, more, r);
return new int[]{less+1, more};
}
private static void swap(int[] arrays, int cur, int r) {
int temp = arrays[cur];
arrays[cur] = arrays[r];
arrays[r] = temp;
}
}
6、堆排
*树是一个逻辑结构,实际上为一个数组存储
第i位置的左孩子的位置为2*i+1
第i位置的右孩子的位置为2*i+2
第i位置的父亲的位置为(i-1)/2
heapInsert():首先将数据形成一个大根堆,从数组的第一个数开始依次寻找父节点的位置,如果比父节点的值大,则交换,直到没有大于该节点的值
heapify():如果一个大根堆,由于一些元素发生了变化,而需要重新整理成大根堆,这个时候用heapify()函数
在快排的过程中,每一次将堆顶最大元素跟数组中最后一个元素交换,下一次循环排除最后一个元素,
在交换之后,需要使用heapify()函数重新找现在根节点的左孩子和右孩子,找到三者中最大的那个值,与之交换,直到数组末尾
*
* 不稳定排序
* 时间复杂度为O(NlogN)
package sort;
public class HeapSort {
public static void main(String[] args) {
int[] nums = new int[]{1,45,23,53,32,32,23};
heapSort(nums);
for (int n: nums){
System.out.print(n+" ");
}
}
public static void heapSort(int[] nums){
if(nums==null || nums.length<2){
return;
}
for (int i=1; i<nums.length; i++){
heapInsert(nums, i);
}
int heapSize = nums.length;
swap(nums, 0, --heapSize);
while (heapSize>0){
heapify(nums, heapSize);
swap(nums, 0, --heapSize);
}
}
public static void heapInsert(int[] nums, int i){
if(nums[i]>nums[(i-1)/2]){
swap(nums, i, (i-1)/2);
i = (i-1)/2;
}
}
public static void heapify(int[] nums, int heapSize){
int i=0;
int left = 2*i+1;
int right = 2*i+2;
while (left < heapSize){
int largest = right< heapSize && nums[right]>nums[left] ? right:left;
largest = nums[largest]>nums[i]?largest:i;
if(largest == i){
break;
}
swap(nums, largest, i);
i=largest;
left = 2*i+1;
right = left+1;
}
}
public static void swap(int[] nums, int i, int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
7、桶排序(基数排序)
//时间复杂度为O(Nlog(r)M)
//r为基数、M为堆数
//不稳定排序
public class BasicSort {
public static void main(String[] args) {
int[] nums = new int[]{1,3,2,7,4,2};
basicSort(nums);
for (int num: nums) {
System.out.print(num);
}
}
public static void basicSort(int[] nums){
int[][] buckets = new int[nums.length][10];
int max = getMax(nums);
//获取每一位数字装到桶中
for (int i=1; max/i>0; i=i*10){
for(int j=0; j<nums.length; i++){
int digit = nums[j]/10;
buckets[j][digit] = nums[j];
}
//将桶中的数据回收,回收出来的数是按照当前装桶位置的元素顺序排列的
int k = 0;
for(int l=0; l<10; l++){
for(int j=0; j<nums.length; j++){
if(buckets[j][l] != 0){
nums[k++] = buckets[j][l];
}
}
}
}
}
public static int getMax(int[] nums){
int max = nums[0];
for(int i=1; i<nums.length; i++){
max = Math.max(max, nums[i]);
}
return max;
}
}