排序算法java实现代码理解

快速排序

我的理解:每次排序都能确定当前基准的位置。
代码实现:

import java.util.Arrays;

public class QuickSort {

	public static void main(String[] args) {
		int[] arr = {3,6,4,5,9,0,2};
		quickSort(arr,0,arr.length-1);
	}
	public static void quickSort(int[] arr, int begin, int end) {
		int i= begin;//左指针
		int j = end;//右指针
		int key = arr[i];//设第一个数字为基准
		//从右侧开始查找比基准小的数字
		while (i<j) {//每个循环中最多执行一次,左指针所在的数值交换+右指针所指向的数值交换。
			while (j>i&&arr[j]>key) j--;
			if (i<j) {//交换
				arr[i] = arr[j];
				i++;
			}
		//从右侧开始查找比基准大的数字
			while (i<j&& arr[i]<key) i++;
			if (i<j) {
				arr[j] = arr[i];
				j--;
			}
		}
		//基准赋值给他应该在的位置
		arr[i] = key;
		System.out.println(Arrays.toString(arr));
		if (i-begin>1) {//基准左侧数组的长度大于1的时候对左侧数组排序
			quickSort(arr, begin, i);
		}
		if (end-i>1) {//基准右侧数组的长度大于1的时候对左侧数组排序
			quickSort(arr, i+1, end);
		}
	}
}

直接选择排序

我的理解:
       每次遍历整个数组,找出最大或最小值,依次排列。他和冒泡排序的区别在于选择排序记录最大元素下标,一次for循环后交换数值,冒泡排序每做一次比较就交换一次数值。
代码实现:

public static void directChooseSort(int[] arr) {
		for(int i=0; i<arr.length; i++){
			int maxIndex = i;//从第i位元素开始比较,假设其为最大元素的下标
			for(int j=i+1; j<arr.length; j++){
				if (arr[j] > arr[i]) {//记录较大元素的下表
					maxIndex = j;
				}
			}
			//将第i位元素与最大元素交换
			int temp = arr[maxIndex];
			arr[maxIndex] = arr[i];
			arr[i]= temp;
		}
		System.out.println(Arrays.toString(arr));
	}

堆排

我的理解:
       1.先构造大顶堆
       2.交换数组中第一个(也就是最大的元素)和最后一个元素(为了取出最大的元素)。
       3.再从第一个元素(对应树中的根节点)构造大顶堆,不考虑最后一个元素所在的节点。
       4.循环2 3步
代码实现:

private static int len;//做排序的时候用到
	public static void main(String[] args) {
		int[] arr = {3,6};
		len = arr.length;
		//构造大顶堆
		for(int i=(int) Math.floor(arr.length/2)-1;i>=0;i--){
			heapChange(arr, i);
		}
		
		System.out.println(Arrays.toString(arr));
		for (int i = arr.length-1; i > 0 ; i--) {
			swap(arr, i, 0);
			len--;//刚交换的节点不参与比较
			heapChange(arr, 0);
		}
		System.out.println(Arrays.toString(arr));
	}
	//构造大顶堆
	public static void heapChange(int[] arr, int i) {
		int s = 2*i;
		if(s<len){//防止递归的时候数组越界
			int key = arr[i];
			int tempMaxIndex = 0;//默认值是0
			boolean changeFlag = false;//保证正确求得左右子树中较大者,而不是根节点
			//二者选其大
			if (s+2<len) {//小于总长度的时候做比较,防止数组越界,此条件下父节点有左右两个子节点
				if (arr[s+1] > arr[s+2]) {
					 tempMaxIndex = s+1;
					 changeFlag = true;
				}else{
					tempMaxIndex = s+2;
					changeFlag = true;
				}
			}else if (s+1<len) {//父节点只有左子节点
				tempMaxIndex = s+1;
				changeFlag = true;
			}
			//key与大者比较交换,交换完成后,对交换的左节点或右节点进行构造大顶堆
			if(changeFlag && key<arr[tempMaxIndex]){
				System.out.println("比较");
				swap(arr, tempMaxIndex, i);
				heapChange(arr, tempMaxIndex);
			}
		}
	}
	//交换方法
	public static void swap(int[] arr,int i,int c) {
		int temp;
		temp = arr[i];
		arr[i] = arr[c];
		arr[c] = temp; 
		System.out.println(arr[i]+","+arr[c]);
	}
直接插入

我的理解:
       数组前面部分是已经排序完成的(第一个元素默认已经排好序,从第二个开始),数组后面部分是需要插入到前面已经排序完成的部分。
       从数组后面部分取元素,每次对比移动前面元素的位置,最后空白的位置即插入的位置。是先找到位置然后放进去。
代码实现:

public static void insertSort(int[] arr){
		
		for (int i = 1; i < arr.length; i++) {//第一个元素默认排好序,从第二个开始
			int insertFlag = i;//待插入的位置默认i即已经是排序好的数组的最大元素
			int insertNum = arr[i];//带插入数字
			for (int j = i; j > 0; j--) {//相当于已经排好序的数组部分
				if (insertNum < arr[j-1]) {
					arr[j] = arr[j-1];//移动
					insertFlag = j-1;//标记待插入位置
				}
			}
			arr[insertFlag] = insertNum;
		}
	}
希尔排序

我的理解:
    计算出跨度,跨度左端边界的数字作为一个插入排序的数组。第一轮跨度为数组长度的一半,第二轮排序跨度在为第一轮的一半。
代码实现:

	private static void shellSort(int[] arr) {
		//i 为跨度
		for (int i = (int) Math.floor(arr.length/2); i > 0 ; i=(int) Math.floor(i/2)) {
			for (int j = i; j < arr.length; j++) {//[3, 6, 8, 4, 5, 3, 9, 4, 0, 1, 78]
				int cur = arr[j];//待排序的值
				int flag = j;//默认位置是当前位置
				while (flag-i>=0 && cur < arr[flag-i]) {
					arr[flag] = arr[flag-i] ;//后移跨度位
					flag = flag-i;
				}
				arr[flag] = cur;
			}
			
		}
	}
计数排序

我的理解:
1.求得最大值和最小值之差,作为辅助数组长度,初始化辅助数组。
2.将原数组的元素的个数放入辅助数组。
3.辅助数组取值依次赋值给原数组。
代码实现:

public static void countSort(int arr[]){
		//获取取最大最小值
		int max=0,min=0;
		for (int i : arr) {
			if (i>max) {
				max= i;
			}
			if (i<min) {
				min = i;
			}
		}
		int k = max - min +1;//设置辅助数组长度
		int[] c = new int[k];
		for (int i : arr) {
			c[i-min]++;//将数值依次放入辅助数组,为了减少数组长度下标统一减去 最小值
		}
		System.out.println("max:"+max+"min:"+min);
		//赋值给arr
		int kv = 0;//归位下标
		for (int i = 0; i < c.length; i++) {
			while (c[i]>0) {
				arr[kv]=i+min;
				kv++;
				c[i]--;
			}
		}
	}
基数排序

我的理解:
      先求得最大数字的位数,将所有元素从按照个位数分组,然后收回数组,在按照十位分组,收回数组,直到最高位分组,收回数组,完成。负数需要经过特殊处理。
代码实现:

public static void radixSort(int[] arr){
		//取最大值
		int i=0;
		int max = arr[i];
		while (i<arr.length) {
			if(max < arr[i]){
				max = arr[i];
			}
			i++;
		}
		int num = 0;//位数
		while (max > 1) {
			max = max/10;
			num++;
		}
		System.out.println("max:"+max);
		System.out.println("num:"+num);
		//第一轮 从低位开始排序
		int tailNum = 0;//个十百位的数字
		int j=0;
		int n = 0;
		while(j<num){
			n = (int) Math.pow(10, j);
			//辅助数组
			int[][] carr = new int[10][arr.length];//存具体数值
			int[] sum = new int[10];//存个数
			for (int an = 0; an < arr.length; an++) {
				
				tailNum = (arr[an]/n)%10;//求得某一位上的数字
				//入数组
				sum[tailNum]++;//一共有几个符合要求的数字
				carr[tailNum][sum[tailNum]-1] = arr[an];//存入辅助数组中
			}
			//将数组赋值给原数组
			int k = 0;//arr 增加指针
			for (int j2 = 0; j2 < carr.length; j2++) {
				if(sum[j2]>0){
					for(int l=0;l<sum[j2];l++){
						arr[k]=carr[j2][l];
						k++;
					}
				}
			}
			j++;
		}	
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值