既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
}
private void quickSortDeal(int[] array, int left, int right) {
if(left >= right) {
return;
}
int index = partition(array,left,right);
quickSortDeal(array,left,index - 1);
quickSortDeal(array,index + 1, right);
}
private int partition(int[] array, int left, int right) {
//选取最左边为基准值
int baseVaule = array[left];
int leftIndex = left;
int rightIndex = right;
while (leftIndex < rightIndex) {
while (leftIndex < rightIndex && array[rightIndex] >= baseVaule) {
rightIndex --;
}
while (leftIndex < rightIndex && array[leftIndex] <= baseVaule) {
leftIndex ++;
}
if(leftIndex < rightIndex) {
int tmp = array[leftIndex];
array[leftIndex] = array[rightIndex];
array[rightIndex] = tmp;
}
}
//此时leftIndex和rightIndex下标的元素一定小于或者等于我们选取的基准值
//若是因为rightIndex下标导致结束循环,那么rightIndex下标未找到比基准值小的数据,最后导致重合。
//若是因为leftIndex下标导致结束循环,那么说明rightIndex已经找到比基准值小的元素,最后重合与基准值交换。
int tmp = array[leftIndex];
array[leftIndex] = array[left];
array[left] = tmp;
return leftIndex;
}
性能分析:
- 时间复杂度
O(NlogN)
- 空间复杂度
O(logN)
非递归实现快排:
思想:运用一个栈记住我们需要处理的left和right下标,再将下标出栈,进行partition操作。
实现:
//非递归实现快速排序
public void quickSortByLoop(int[] array) {
Stack stack = new Stack<>();
//左边界先入栈
stack.push(0);
stack.push(array.length - 1);
while (!stack.isEmpty()) {
//右边界先出栈
int right = stack.pop();
int left = stack.pop();
if(left >= right) {
continue;
}
int index = partition(array, left,right);
//讲左边区间入栈,还要注意左边界先入栈
stack.push(left);
stack.push(index - 1);
//将右边区间入栈
stack.push(index + 1);
stack.push(right);
}
}
private int partition(int[] array, int left, int right) {
//选取最左边为基准值
int baseVaule = array[left];
int leftIndex = left;
int rightIndex = right;
while (leftIndex < rightIndex) {
while (leftIndex < rightIndex && array[rightIndex] >= baseVaule) {
rightIndex --;
}
while (leftIndex < rightIndex && array[leftIndex] <= baseVaule) {
leftIndex ++;
}
if(leftIndex < rightIndex) {
int tmp = array[leftIndex];
array[leftIndex] = array[rightIndex];
array[rightIndex] = tmp;
}
}
//此时leftIndex和rightIndex下标的元素一定小于或者等于我们选取的基准值
//若是因为rightIndex下标导致结束循环,那么rightIndex下标未找到比基准值小的数据,最后导致重合。
//若是因为leftIndex下标导致结束循环,那么说明rightIndex已经找到比基准值小的元素,最后重合与基准值交换。
int tmp = array[leftIndex];
array[leftIndex] = array[left];
array[left] = tmp;
return leftIndex;
}
优化快速排序:
-
快排的性能受基准值的影响很大,如果我们选的基准值接近数组中的中位数,此时左右俩个区间较均衡性能也最好。
-
所以我们需要优化基准值,随机挑三个数字,取三个数字的中间值作为基准值。
实现:
//优化后的快速排序
public void betterQuickSort(int[] array) {
betterQuickSortDeal(array, 0, array.length - 1);
}
private void betterQuickSortDeal(int[] array, int left, int right) {
if(left >= right) {
return;
}
int index = betterQartition(array,left,right);
betterQuickSortDeal(array,left,index - 1);
betterQuickSortDeal(array,index + 1, right);
}
private int betterQartition(int[] array, int left, int right) {
int baseVaule = findBetterBaseVaule(array, left, right);
int leftIndex = left;
int rightIndex = right;
while (leftIndex < rightIndex) {
while (leftIndex < rightIndex && array[rightIndex] >= baseVaule) {
rightIndex --;
}
while (leftIndex < rightIndex && array[leftIndex] <= baseVaule) {
leftIndex ++;
}
if(leftIndex < rightIndex) {
int tmp = array[leftIndex];
array[leftIndex] = array[rightIndex];
array[rightIndex] = tmp;
}
}
int tmp = array[leftIndex];
array[leftIndex] = array[left];
array[left] = tmp;
return leftIndex;
}
private int findBetterBaseVaule(int[] array, int left, int right) {
if(array.length < 3) {
return array[left];
}
int[] nums = new int[3];
nums[0] = array[left];
nums[1] = array[right];
Random rand = new Random();
//选取(left,right)下标中间的一个随机值
int ra = rand.nextInt(right) + left + 1;
nums[2] = array[ra];
Arrays.sort(nums);
for (int i = 0; i < array.length; i++) {
if(array[i] == nums[1]) {
array[i] = array[left];
array[left] = nums[1];
break;
}
}
return array[left];
}
-
还有优化方式就是当我们当前这个区间数组元素个数较少时,我们直接进行插入排序,
-
再就是当我们递归达到一定深度的时候,此时待排区间还有很多时,我们使用堆排序。
归并排序-原理(稳定)(重要)
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
实现:
//归并排序
public void mergeSort(int[] array) {
//归并排序区间采用左闭右开格式,快排采用左闭右闭格式
mergeSortHealper(array, 0, array.length);
}
private void mergeSortHealper(int[] array, int left, int right) {
if(right - left <= 1) {
return;
}
int mid = (left + right) / 2;
mergeSortHealper(array,left,mid);
mergeSortHealper(array,mid,right);
merge(array,left,mid,right);
}
//将俩个有序序列合并为一个有序序列
private void merge(int[] array, int left, int mid, int right) {
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
俩个有序序列合并为一个有序序列
private void merge(int[] array, int left, int mid, int right) {
[外链图片转存中…(img-TDcK8k73-1715676452560)]
[外链图片转存中…(img-9aAVPGr3-1715676452560)]
[外链图片转存中…(img-TDkuwyG4-1715676452561)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新