java—各种排序算法

版权声明:071623 https://blog.csdn.net/weixin_43584220/article/details/88672875

1.冒泡排序BubbleSort
2.快速排序QuickSoet
3.插入排序InsertSort
4.希尔排序ShellSort
5.选择排序SelectSort
6.归并排序MergeSort
7.基数排序RadixSort
8.队列排序RadixQueueSort
9.堆排序HeapSort


1.BubbleSort

package cn.DataStructureAndAlgorithms.Ravanla.copy;

import java.util.Arrays;

/*
 * 冒泡排序
 */
public class TestBubbleSort {
	public static void main(String[] args) {
		int[] arr1 = new int[] {5, 7, 4, 3, 7, 3, 9, 1, 0};
		bubbleSort(arr1);
		System.out.println(Arrays.toString(arr1));
	}
	public static void bubbleSort(int[] arr) {
		for(int i = 0; i < arr.length-1; i++) {
			for(int j = 0; j < arr.length - 1 - i; j++) {
				if(arr[j] > arr[j + 1]){
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
			}
		}
	}
}
//BubbleSort在我的博客中另一篇文章有详细的介绍
//https://blog.csdn.net/weixin_43584220/article/details/88363065


在这里插入图片描述


2.QuickSort

package cn.DataStructureAndAlgorithms.Ravanla.copy;
import java.util.Arrays;
/*
 * 快速排序
 * @author Ravanla
 * 思路:
 * 1.需要形参有开头start和结尾end
 * 2.如果start < end就递归自己
 * 3.把下标为0(也可以是其他下标)的值设为标准值 
 * 把开头和结束分别设置为低位(low)和高位(high)
 * 4.当low<high时循环执行
 *  1.(low<high时)高位的值大于标准值,把高位减一位,直到小于时把当前高位的值赋值给低位
 *  2.(low<high时)低位的值小于标准值,把低位减一位,直到大于时把当前低位的值赋值给高位
 * 5.执行完后此时的高位和低位相等,把标准值赋值给低位or高位的值   
 * (low<high时)保证高位一定等于低位出循环
 * 6.此时的数组分为(low右边)大于标准值和(low左边)小于标准值    
 * 然后分两边递归调用自己  
 * 7.直到start >= end(low >= high)不会递归下去
 */
public class TestQuickSort {
	public static void main(String[] args) {
		int[] arr2 = new int[] {5, 7, 4, 3, 7, 3, 9, 1, 0};
		System.out.println(Arrays.toString(arr2));
		QuickSort(arr2, 0, arr2.length - 1);
		System.out.println(Arrays.toString(arr2));
	}
	public static void QuickSort(int[] arr,int start, int end){
		if(start < end){
			int low = start;
			int high = end;
			int standard = arr[low];
			while(low < high){
				while(low < high && standard < arr[high])high--;
				if(low < high) arr[low++] = arr[high];
				while(low < high && standard > arr[low])low++;
				if(low < high) arr[high--] = arr[low];
			}
			arr[low] = standard;
			QuickSort(arr, start, low - 1);
			QuickSort(arr, low + 1, end);
		}
	}
}

在这里插入图片描述


3.InsertSort

package cn.DataStructureAndAlgorithms.Ravanla.copy;
/**
 * 
 * @author Ravanla
 * 思路:
 * 1.设置i从1开始遍历全数组
 *  1.如果下标i的值小于前(左)一个数
 *   1.把下标i的值赋值给temp
 *   2.设置j为i的前(左)一个下标
 *    1.如果temp还是小于下标为j的值,将下标j的值赋值给j后面(右)一个下标
 *    	并将j指向前(左)一个下标
 *   3.把temp赋值给j后面(右)一个下标
 */
import java.util.Arrays;

public class TestInsertSort {
	public static void main(String[] args) {
		int[] arr = new int[] {5, 7, 4, 3, 7, 3, 9, 1, 0};
		insertSort(arr);
		System.out.println(Arrays.toString(arr));
	}
	public static void insertSort(int[] arr) {
		for(int i = 1; i < arr.length; i++) {
			if(arr[i] < arr[i - 1]) {
				int temp = arr[i];
				int j;
				for(j = i - 1; j >= 0 && temp < arr[j]; j--) {
					arr[j + 1] = arr[j];
				}
				arr[j + 1] = temp;
			}
		}
		
	}
}

在这里插入图片描述


4.ShellSort

package cn.DataStructureAndAlgorithms.Ravanla.copy;

import java.util.Arrays;

/*
 * 希尔排序
 * @author Ravanla
 * 思路:
 * 1.设置一个增量s,记录每次arr的长度除以2的值
 * 	1.设置一个i等于这个s,i从这个数组的一半开始每次循环加一
 * 	 1.设置一个j等于i - s,每次减s个增量,减到小于0为止
 * 	  1.在这里进行下标i和下标j的值的对比
 * 当增量序列为dlta[k]=2t-k+1-1(0≤k≤t≤⌊log2(n+1)⌋)时,可以获得不错的效率
 */
public class TestShellSort {
	public static void main(String[] args) {
		int[] arr = new int[] {5, 7, 4, 3, 7, 3, 9, 1, 0};
		System.out.println(Arrays.toString(arr));
		ShellSort(arr);
		System.out.println(Arrays.toString(arr));
	}
	public static void ShellSort(int[] arr) {
		for(int s = arr.length/2; s > 0; s/=2) {
		//s
			for(int i = s; i < arr.length; i++) {
//				for(int j = i - s; j < arr.length; j+=s)
				for(int j = i - s; j >= 0; j-=s){
				//第一次的i - s就等于0   表示arr[j]从数组下标零开始  
				//每隔s个位置经行比较
				//之后的i - s
					if(arr[i] < arr[j]) {
						int temp = arr[i];
						arr[i] = arr[j];
						arr[j] = temp;
					}
				}
			}
		}
	}
}

在这里插入图片描述


5.SelectSort

package cn.DataStructureAndAlgorithms.Ravanla.copy;
/*
 * 选择排序
 * 思路:
 * 1.遍历全数组
 * 2.把下标为0设为最小值的下标,并开始遍历该下标以后是否有比它小的元素,
 * 如果有把该下标设为最小值的小标
 * 3.把最小值的小标与遍历到当前下标的i的值 调换
 */
import java.util.Arrays;

public class TestSelectSort {
	public static void main(String[] args) {
		int[] arr = new int[] {5, 7, 4, 3, 7, 3, 9, 1, 0};
		System.out.println(Arrays.toString(arr));
		SelectSort(arr);
		System.out.println(Arrays.toString(arr));
	}
	public static void SelectSort(int[] arr) {
		for(int i = 0; i < arr.length; i++) {
			int min = i;
			for(int j = i + 1; j < arr.length; j++) {
				if(arr[min] > arr[j]) {
//					int temp = arr[min];
//					arr[min] = arr[j];
//					arr[j] = temp;
					min = j;
				}
			}
			if(i != min) {
				int temp = arr[i];
				arr[i] = arr[min];
				arr[min] = temp;
			}
		}
	}
}


在这里插入图片描述


6.MergeSort

package cn.DataStructureAndAlgorithms.Ravanla.copy;

import java.util.Arrays;
//归并排序
/**
 * 
 * @author Ravanla
 * 思路:
 * merge(归并)函数
 * 1.把一个数组想象成两个等份(相差不过1)的数组   左边的低位(i = low)到高位(middle)
 * 右边的低位(j = middle + 1)到高位(high)
 * 2.设置index指向装入下标
 * 3.设置备份数组,数组长度由递归过来的数组的长度决定,
 * 因为high=arr.length-1传过来的-1,在保证temp数组与传入的数组长度一样,所以要+1
 * 4.在两边数组的低位都还没超过(相应的)高位的情况下经行比较,
 * 把小(或大)的放在temp左(或右)边
 * index(从0到arr.length/2)指向放入位置的下标
 * 5.把还没超过(相应的)高位的数组,把剩下的数依次放入temp数组直到遍历到(相应的)高位为止
 * 6.剩下一个步骤要结合mergeSort函数来理解
 * 
 * mergeSort(递归调用归并函数)函数
 * 1.在低位低于高位的情况下
 * 2.设置middle
 * 3.递归自己(把子拆成等分[相差不过1]的两半,递归调用)
 * 4.最后调用归并函数-------------看到这里可以理解为
 * 一个数组以每两个元素分成一组,每一组都经行大小比较
 * 一轮结束后每四个元素分为一组....
 * 所以merge函数的最后一步这样理解比较好
 * arr下标 		0    和    1      2    和    3     4和5
 * value值   		4     3      2     1
 *             low   high | low   high
 * temp的下标          0  和    1   |  0  和    1
 * temp数组的元素    3     4   |  1     2
 * 
 */
public class TestMergeSort {
	public static void main(String[] args) {
		int[] arr = new int[] {5, 7, 4, 3, 7, 3, 9, 1, 0};
		System.out.println(Arrays.toString(arr));
		mergeSort(arr, 0, arr.length - 1);
		System.out.println(Arrays.toString(arr));
		//先看merge函数
	}
	public static void mergeSort(int[] arr, int low, int high) {
		int middle = (high + low)/2;
		if(low < high) {
			mergeSort(arr, low, middle);
			mergeSort(arr, middle + 1, high);
			//把一个数组分成两份  然后进行归并递归调用 直到low<high结束调用
			merge(arr, low, middle, high);
		}
	}
	public static void merge(int[] arr, int low, int middle, int high) {
	//low				middle					high
	// 5,  	 7, 4,	 	  3, 	 7, 3, 9, 1, 	 0
		int i = low;
		int j = middle + 1;
		int index = 0;
		int[] temp = new int[high - low + 1];
		//这个临时数组的长度为high - low + 1   high传进来时是length-1
//		while(i < j && j < arr.length)
		while(i <= middle && j <= high){
		//把一个数组分成两个数组进行比较
			if(arr[i] <= arr[j]) {
				temp[index] = arr[i];
				i++;
				index++;
			}
			else {
				temp[index] = arr[j];
				j++;
				index++;
			}
			//把分成的两数组中最小的数依次放入temp   
		}
		//两数组中较大的数赋值给剩下一半数组长度的temp
		while(i <= middle) {
			temp[index] =arr[i];
			i++;
			index++;
		}
		while(j <= high) {
			temp[index] = arr[j];
			j++;
			index++;
		}
		//然后把temp归并好的数传给arr
	//	for(int k = 0; k <= high; k++) {
		//	arr[k + low] = temp[k];
		//}
		//arr.length - 1  ->  high
		//temp.length   ->   (high - low + 1)
		//思考为什么上面一个写法会错
		for(int k = 0; k < temp.length; k++) {
			arr[k + low] = temp[k];
			//下次归并时low会变
		}
		//这就归并好一次啦
		//然后利用mergeSort递归调用它
	}
}
//明天续更,今晚充能

在这里插入图片描述


7.RadixSort

package cn.DataStructureAndAlgorithms.Ravanla.copy;

import java.util.Arrays;

public class TestRadixSort {
	public static void main(String[] args) {
		int[] arr = new int[] {53, 274, 4, 43, 7, 3, 239, 141, 432};
		RadixSort(arr);
		System.out.println(Arrays.toString(arr));
	}
	public static void RadixSort(int[] arr) {
		int max = Integer.MIN_VALUE;
		//最大值为Integer.MAX_VALUE,即2147483647,最小值为Integer.MIN_VALUE 
		//-2147483648
		//找到数组中的最大值
		for(int i = 0; i < arr.length; i++) {
			if(arr[i] > max) {
				max = arr[i];
			}
		}
		int maxlength = (max + "").length();
		//将最大的数变为字符串,求字符串长度,此时的长度为数位大小
		//https://baike.baidu.com/item/%E6%95%B0%E4%BD%8D/6157143?fr=aladdin
		int[][] temp = new int[10][arr.length];
		//第一次找到274,百位为2,2放在temp
		int[] count = new int[10] ;
		for(int i = 0, n = 1; i < maxlength; i++, n*=10) {
			for(int j = 0; j < arr.length; j++) {
				int ys = (arr[j]/n)%10;
				temp[ys][count[ys]] = arr[j];
				count[ys]++;
				//看图
			}
//			if(i == 0) {
//				for(int[] nums:temp) {
//					System.out.println(Arrays.toString(nums));
//				}
//				System.out.println(Arrays.toString(count));
//			}
			int index = 0;
			for(int k = 0; k < count.length; k++) {
			//遍历0,1,2,3,4..., 9
				if(count[k] != 0) {
					for(int o = 0; o < count[k]; o++) {
					//遍历count的数
						arr[index] = temp[k][o];
						index++;
					}
					//每一次遍历完将当前计数设置为0,以便下次计数为0时不会记录相同的数
					count[k] = 0;
				}
			}
		}
		
	}
}


在这里插入图片描述
在这里插入图片描述


8.RadixQueueSort 有错误 基数队列排列先不看

package cn.DataStructureAndAlgorithms.Ravanla;
import java.util.Arrays;
/*
 * 测试基数排序之队列方法
 */
public class TestRadixQueueSort {
	public static void main(String[] args) {
		int[] arr = new int[10];
		Queue q = new Queue(arr);
		//长度溢出
		q.offer(2);
		q.offer(3);
		q.offer(4);
		q.offer(5);
		q.offer(6);
		q.peek(arr);
	}
}

class Queue{
	int[] arr1 = new int[15];
	public Queue(int[] arr1) {
		this.arr1 = arr1;
	}
//	poll弹出首个元素  remove
//	查看元素peek  element
//	offer在尾部添加   add     
//	前面的单词在异常时都会返回一个值 ,后面的则会抛出异常
	public int poll() {
		int a = arr1[0];
		int[] temp = new int[arr1.length - 1];
		for(int i = 0; i < arr1.length - 1; i++) {
			temp[i] = arr1[i + 1];
		}
		arr1 = temp;
		return a;
	}
	
	public void offer(int a) {
		int[] temp = new int[arr1.length + 1];
		for(int i = 0; i < arr1.length + 1; i++) {
		//下面这个语句错误的
			temp[i + 1] = arr1[i];
		}
		temp[0] = a;
		arr1 = temp;
	}
	public void peek(int[] arr) {
		System.out.println(Arrays.toString(arr));
	}
}


9.HeapSort

下面数组所表达的是二叉树的排序,但是这个二叉树有点乱,接下来将它排序

在这里插入图片描述

package cn.DataStructureAndAlgorithms.Ravanla.copy;

import java.util.Arrays;

public class TestHeapSort {
	public static void main(String[] args) {
		int[] arr = new int[] {5, 7, 4, 3, 7, 3, 9, 1, 0};
		int start = (arr.length - 1)/2;
		HeapSort p = new HeapSort();
		p.arr = arr;
		p.size = arr.length;
		for(int i = start; i >= 0; i--) {
			p.index = i;
			p.MaxHeap(i);
//			这里有缺陷,但是不知道怎么改会比较好
			
		}
		for(int j = arr.length - 1; j >=0; j--) {
				int temp = arr[0];
				arr[0] = arr[j];
				arr[j] = temp;
				p.size = j;
				p.MaxHeap(0);
			}
		System.out.println(Arrays.toString(arr));
	}
	
}


排成大顶堆后,将大顶堆的根放在最后,然后继续排

package cn.DataStructureAndAlgorithms.Ravanla.copy;

public class HeapSort {
	int[] arr = new int[8];
//	这里缺陷非常明显,不够灵活
	int size;
	int index;
	public HeapSort() {
		
	}
//	public HeapSort(int[] arr, int size, int index) {
//		this.arr = arr;
//		this.size = size;
//		this.index = index;
//	}
	public void MaxHeap(int index) {
		int leftNode = 2 * index + 1;
		int rightNode = 2 * index + 2;
		int max = index;
//		if(leftNode < size && arr[leftNode] > arr[max]) {
//			int temp = arr[leftNode];
//			arr[leftNode] = max;
//			arr[max] = temp;
//		}
//		if(rightNode < size && arr[rightNode] > arr[max]) {
//			int temp = arr[rightNode];
//			arr[rightNode] = max;
//			arr[max] = temp;
//		}
		if(leftNode < size && arr[leftNode] > arr[max]) {
			max = leftNode;
		}
		if(rightNode < size && arr[rightNode] > arr[max]) {
			max = rightNode;
		}
		if(max != index) {
			int temp = arr[max];
			arr[max] = arr[index];
			arr[index] = temp;
			MaxHeap(max);
		}
	}
	public void heapSort(int[] arr) {
		
	}
}


猜你喜欢

转载自blog.csdn.net/weixin_43584220/article/details/88672875