归并排序的JAVA实现
归并排序的核心思想是分治,写成代码就是递归。
递归终止条件是:数组中只有一个元素
时间复杂度是
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)。个人理解,分解合并的高度一共为
2
l
o
g
n
2logn
2logn。每一层的时间复杂度为n,比如说合并时,合并一排数字时间复杂度为n。与层高相乘就是
n
l
o
g
n
nlogn
nlogn。此处仅仅个人理解,谨慎参考。至于为什么分解合并的高度一共为
2
l
o
g
n
2logn
2logn,参考二分查找的时间复杂度进行理解。
二分查找的时间复杂度分析
图片来自 极客时间 中的专栏 数据结构与算法之美。

public class Sort {
public static void main(String[] args) {
int[] nums = {1, 5, 6, 2, 3, 4};
merger_sort(nums, 0, nums.length - 1);
for (int a: nums) {
System.out.println(a);
}
}
//归并排序
//merger_sort函数的作用:将数组nums中下标从start到end的元素排序。
public static void merger_sort(int[] nums, int start, int end) { //左闭右闭
if (start >= end) { //终止条件,数组中只有一个元素
return ;
}
int mid = (start + end) / 2;
merger_sort(nums, start, mid);
merger_sort(nums, mid + 1, end);
merge(nums, start, mid, end);
}
public static void merge (int[] nums, int start, int mid, int end) { //合并
int[] temp = new int[end - start + 1];
int i = start;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= end) {
if (nums[i] < nums[j]) {
temp[k++] = nums[i];
i++;
} else {
temp[k++] = nums[j];
j++;
}
}
while (i <= mid) {
temp[k++] = nums[i++];
}
while (j <= end) {
temp[k++] = nums[j++];
}
k = 0;
i = start;
for(; i <= end; i++,k++) {
nums[i] = temp[k];
}
}
}
快速排序的JAVA实现
核心思想:
每次选择一个数据作为分区点,然后将数组中小于这个数字的元素放到左边,将数组中大于这个数字的元素放到右边。也就是说,每次会将一个元素放到正确的位置,然后同样的处理,排序后,这个元素两边的子数组。
时间复杂度
关于快排时间复杂度的个人理解。每次排序都需要处理n个数字。
当数组有序时,每次支点不能分割数组,所以,一共需要n次找支点的过程。故相乘之后之间复杂度为
O
(
n
2
)
O(n^{2})
O(n2)
当数组无序时,最好情况,每次分割可以正好将数组分成两半,所以,一共需要
l
o
g
n
logn
logn次找支点的过程,故相乘之后的时间复杂度为
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
public class Sort{
public static void main(String[] args) {
int[] nums = {1,3,5,4,2};
quickSort(nums, 0, nums.length - 1);
for (int a : nums) {
System.out.println(a);
}
}
//快速排序
public static void quickSort(int[] nums, int start, int end) { //左闭右闭
if (start >= end) { //当数组中只有一个元素的时候终止
return ;
}
int pIndex = findPIndex(nums, start, end);
quickSort(nums, start, pIndex - 1);
quickSort(nums, pIndex+1, end);
}
//获取分区数组的正确下标
public static int findPIndex(int[] nums, int start, int end) {
//选择最后一个数字作为支点 nums[end]
int left = start;
int right = end - 1;
while(left <= right) {
while (nums[left] < nums[end]) { //找到左边的比该元素数字大的元素
left ++;
}
while (nums[right] >= nums[end]) { //找到右边的比该元素数字小的元素
right --;
}
if (left < right) { //交换刚才找到的两个数字
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
}
}
int temp = nums[left]; //将支点归位,因为left指针指向的是比支点大的元素,所以交换以后,这个元素放到了支点右边是合适的。
nums[left] = nums[end];
nums[end] = temp;
return left;
}
}
文章详细介绍了如何使用JAVA编程语言实现归并排序和快速排序两种经典算法,包括它们的核心思想、时间复杂度分析以及具体的代码实现。归并排序的时间复杂度为O(nlogn),而快速排序在最好情况下时间复杂度也为O(nlogn),但最坏情况下为O(n^2)。

348

被折叠的 条评论
为什么被折叠?



