Java实现排序算法 1:冒泡排序+选择排序+插入排序+堆排序+快速排序

class Sort {
	/**
	 * 排序算法之冒泡排序
	 * @author 赵庚东
	 * 时间复杂度:O(N^2)
	 * 空间复杂度:O(1)
	 * 稳定性:稳定排序
	 * 大概思路:如果有N个元素将要进行比较大小,进行N-1次循环,每次循环找出当前部分中最大的数放到
     *          该部分最后。
	 */
	public static void bubble(int[] arr,int size) {
		if(size <= 1) {
			return;
		}
        //遍历N-1次
		for(int i = 0;i < size - 1;i++) {
            //每次只需比较未排序部分
			for(int j = 0;j < size - i - 1;j++) {
                //如果后面的元素比当前元素小,将当前元素与后一个元素进行交换
				if(arr[j] > arr[j + 1]) {
					MyMethod.swap(arr, j, j + 1);
				}
			}
		}
	}
	
	/**
	 * 排序算法之选择排序
	 * @author 赵庚东
	 * 时间复杂度:O(N^2)
	 * 空间复杂度:O(1)
	 * 稳定性:不稳定排序
	 * 大概思路:存在一个有序区间【0,bound)和一个无序区间【bound,size)
	 * 每次便利无序区间,从中找到一个最小的 值,放到当前bound处
	 * arr【bound】作为擂台
	 */
	public static void select (int[] arr,int size) {
		if(size <= 1) {
			return;
		}
		int bound = 0;
		for(;bound < size;bound++) {
			int cur = bound;
			//在无序区间中找出最小元素
			for(;cur < size;cur++) {
				if(arr[cur] < arr[bound]) {
					// cur 位置处的数比bound处的数小,
					// 那么cur处的那个数占领擂台,
					// 我们始终要让bound处的数为最小值
					// 所以将cur处与bound处的数进行交换,使得bound处的数为最小值。
					MyMethod.swap(arr, cur, bound);
				}
			}
		}
		return;
	}
	/**
	 * 排序算法之插入排序
	 * @author 赵庚东
	 * 大概思路:有一个有序区间【0,bound)和无序区间【bound,size)
	 * 每一次将bound处的数字插入到前面的有序区间当中
	 * 时间复杂度:O(N^2)
	 * 空间复杂度:O(1)
	 * 稳定排序
	 */
	public static void insert(int[] arr,int size) {
		if(size <= 1) {
			return;
		}
		int bound  = 1;
		for(;bound < size;bound++) {
			int boundVal = arr[bound];
			int i = bound;
			for(;i > 0;i--) {
				if(arr[i - 1] > boundVal) {
					//如果bound前面的数字比bound处的数字大,就开始进行搬运
					arr[i] = arr[i - 1];
				}else {
					//已经给boundVal找到一个合理的位置
					//当前数组的这个元素已经小于boundVal,将boundVal直接放到arr【i】处
					//arr[i] = boundVal;
					break;
				}
			}
			//循环执行完毕有两种情况:①、上面循环已经为boundVal找到合适的位置,②、一直没有找到合适位置,但是循环已经结束
			//第二种情况其实就是boundVal是有序区间里最小的元素。
			arr[i] = boundVal;
		}
	}
	/**
	 * 排序算法之堆排序
	 * 升序建大堆,降序建小堆
	 * @author 赵庚东
	 * 大概思路:建大堆->循环删除堆顶元素,将堆顶元素与当前数组的最后一个元素进行交换->再进行向下调整
	 */
	public static void Heap(int[] arr,int size) {
		if(size <= 1) {
			return;
		}
		//1、建堆
		HeapCreate(arr,size);
		//2、循环删除堆顶元素
		int i = 0;
		for(;i < size; i++) {
			heapPop(arr,size - i);
		}
	}
	public static void HeapCreate(int[] arr,int size) {
		if(size <= 1) {
			return;
		}
		//向下调整:需要从后往前遍历
		//从最后一个非叶子节点开始遍历
		//size - 1表示最后一个元素的下标
		//拿着这个下表 -1 / 2,就找到了当前元素的父节点
		int i = (size - 1 - 1) / 2;
		for(;i > 0;i--) {
			adJustDown(arr, size, i);
		}
	}
	//下面方法创建一个大堆:要求左右子树小于父节点
	//index表示从当前下标开始向下调整
	public static void adJustDown(int[] arr,int size,int index) {
		int parent = index;
		int child = 2 * parent + 1;//左子树
		while(child < size) {
			//先拿左右字数进行比较,看谁比较大,然后再拿大的跟父节点进行比较
			if(child + 1< size && arr[child + 1] > arr[child]) {
				child += 1;//child为当前父节点的右子树
			}
			//child处的值为当前父节点左右孩子中最大的
			if(arr[child] > arr[parent]) {
				MyMethod.swap(arr, child, parent);
			}else {
				break;
			}
			parent = child;
			child = 2 * parent + 1;
		}
		return;
	}
	//循环删除操作先将当前堆顶元素与当前数组最后一个元素进行交换,然后再进行向下调整。
	public static void heapPop(int[] arr,int size) {
		if(size <= 1) {
			return;
		}
		MyMethod.swap(arr, 0, size - 1);
		adJustDown(arr, size - 1, 0);
	}
	/**
	 * 排序算法之快速排序
	 * @author 赵庚东
	 * 大概思路:找一个基准值,将当前数组中每一个元素与这个基准值相比
	 * 比基准值小的全部放到基准值左边,比基准值大的全部放到基准值右边
	 * 每次返回这个基准值的下标,然后对左右两边继续进行上述操作
	 * 平均时间复杂度:O(nlogn)
	 * 最差时间复杂度:O(n^2)
	 * 平均空间复杂度:O(logn)
	 * 最差空间复杂度:O(n)
	 * 不稳定排序
	 */
	//left表示当前数组需要被调整部分的第一个元素,right表示当前数组需要被调整部分的最后一个元素
	public static void quick(int[] arr,int left,int right) {
		if(left >= right) {
			return;
		}
		int pivotIndex = partition(arr, left, right);//基准值所在下标
		quick(arr, left, pivotIndex - 1);//对基准值左边进行处理
		quick(arr, pivotIndex + 1, right);//对基准值右边进行处理
	}
	public static int partition(int[] arr,int left,int right) {
		int pivot = arr[right];//将当前数组的最右边当作基准值
		int tail = left - 1;   //tail表示小于基准值那部分的最后一个元素
		for(int i = 0;i < right;i++) {
			if(arr[i] <= pivot) {
				MyMethod.swap(arr, ++tail, i);//将数组中小于基准值的数与tail+1处的数进行交换,对tail自增
			}
		}
		MyMethod.swap(arr, tail + 1, right);//将基准值与第一个比基准值大的书进行交换
		return tail + 1;//返回基准值所在下标
	}
}


class MyMethod {
	public static void swap(int arr[],int x,int y) {
		int c = arr[x];
		arr[x] = arr[y];
		arr[y] = c;
	}
}

后续还会带来其它排序算法!

猜你喜欢

转载自blog.csdn.net/weixin_41890097/article/details/81748585