快速排序
public class QuickSort {
/**
* 快速排序主函数
*
* @param arr 待排序的数组
* @param left 排序的起始位置
* @param right 排序的结束位置
*/
public static void quickSort(int[] arr, int left, int right) {
if (left < right) {
// 选择一个基准元素,并找到其正确的位置
int pivotIndex = partition(arr, left, right);
// 递归地对基准元素左侧和右侧的子数组进行快速排序
quickSort(arr, left, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, right);
}
}
/**
* 分区操作,找到基准元素的正确位置
*
* @param arr 待分区的数组
* @param left 分区的起始位置
* @param right 分区的结束位置
* @return 基准元素的正确位置(索引)
*/
private static int partition(int[] arr, int left, int right) {
// 选择最右侧的元素作为基准元素
int pivot = arr[right];
int i = left - 1; // 初始化i为小于基准元素值的元素的索引
for (int j = left; j < right; j++) {
// 如果当前元素小于或等于基准元素
if (arr[j] <= pivot) {
i++; // 增加i
// 交换arr[i]和arr[j]
swap(arr, i, j);
}
}
// 将基准元素交换到正确的位置
swap(arr, i + 1, right);
return i + 1;
}
/**
* 交换数组中两个元素的位置
*
* @param arr 数组
* @param i 第一个元素的索引
* @param j 第二个元素的索引
*/
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 测试快速排序
public static void main(String[] args) {
int[] arr = {10, 7, 8, 9, 1, 5};
quickSort(arr, 0, arr.length - 1);
for (int num : arr) {
System.out.print(num + " ");
}
}
}
在这个示例中,quickSort
方法是快速排序的主函数,它接收一个数组和要排序的起始和结束位置作为参数。它首先检查起始位置是否小于结束位置,如果是,则选择一个基准元素,并调用 partition
方法来找到基准元素的正确位置。然后,它递归地对基准元素左侧和右侧的子数组进行快速排序。
partition
方法是快速排序的关键部分,它选择一个基准元素(在这个示例中,我们选择最右侧的元素作为基准元素),然后遍历数组,将所有小于或等于基准元素的元素移动到基准元素的左侧,将所有大于基准元素的元素移动到基准元素的右侧。最后,它将基准元素交换到其正确的位置,并返回其索引。
swap
方法是一个辅助方法,用于交换数组中两个元素的位置。
在 main
方法中,我们创建了一个待排序的数组,并调用 quickSort
方法来对其进行排序。然后,我们遍历排序后的数组并打印每个元素。
归并排序(Merge Sort)
public class MergeSort {
/**
* 归并排序主函数
*
* @param arr 待排序的数组
*/
public static void mergeSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
// 使用临时数组来存储排序结果
int[] temp = new int[arr.length];
// 调用归并排序的内部函数
mergeSortInternal(arr, temp, 0, arr.length - 1);
}
/**
* 归并排序的内部函数
*
* @param arr 待排序的数组
* @param temp 临时数组
* @param left 左边界
* @param right 右边界
*/
private static void mergeSortInternal(int[] arr, int[] temp, int left, int right) {
// 如果左边界大于等于右边界,则无需排序
if (left >= right) {
return;
}
// 找到中间位置
int mid = left + (right - left) / 2;
// 对左半部分进行归并排序
mergeSortInternal(arr, temp, left, mid);
// 对右半部分进行归并排序
mergeSortInternal(arr, temp, mid + 1, right);
// 合并两个已排序的半部分
merge(arr, temp, left, mid, right);
}
/**
* 合并两个已排序的半部分
*
* @param arr 待合并的数组
* @param temp 临时数组
* @param left 左半部分的起始索引
* @param mid 中间索引
* @param right 右半部分的结束索引
*/
private static void merge(int[] arr, int[] temp, int left, int mid, int right) {
// 左边和右边的起始索引
int i = left;
int j = mid + 1;
// 合并元素到临时数组temp中
int t = 0;
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[t++] = arr[i++];
} else {
temp[t++] = arr[j++];
}
}
// 拷贝左边剩余的元素(如果有)
while (i <= mid) {
temp[t++] = arr[i++];
}
// 拷贝右边剩余的元素(如果有)
while (j <= right) {
temp[t++] = arr[j++];
}
// 将临时数组temp的元素拷贝回arr
t = 0;
int k = left;
while (k <= right) {
arr[k++] = temp[t++];
}
}
// 测试归并排序
public static void main(String[] args) {
int[] arr = {10, 7, 8, 9, 1, 5};
mergeSort(arr);
for (int num : arr) {
System.out.print(num + " ");
}
}
}
在这个示例中,mergeSort
方法是归并排序的入口点,它首先检查数组是否为空或长度小于2(此时无需排序)。然后,它创建一个临时数组,并调用 mergeSortInternal
方法来执行实际的排序操作。
mergeSortInternal
方法是递归地将数组分成两半,并对每一半进行排序。一旦两半都排好序,就调用 merge
方法将它们合并成一个有序的数组。
merge
方法负责合并两个已排序的半部分。它使用临时数组来存储合并的结果,然后将结果复制回原始数组。
在 main
方法中,我们创建了一个待排序的数组,并调用 mergeSort
方法来对其进行排序。然后,我们遍历排序后的数组并打印每个元素。
归并排序(Merge Sort)
public class MergeSort {
/**
* 归并排序主函数
*
* @param arr 待排序的数组
*/
public static void mergeSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
// 使用临时数组来存储排序结果
int[] temp = new int[arr.length];
// 调用归并排序的内部函数
mergeSortInternal(arr, temp, 0, arr.length - 1);
}
/**
* 归并排序的内部函数
*
* @param arr 待排序的数组
* @param temp 临时数组
* @param left 左边界
* @param right 右边界
*/
private static void mergeSortInternal(int[] arr, int[] temp, int left, int right) {
// 如果左边界大于等于右边界,则无需排序
if (left >= right) {
return;
}
// 找到中间位置
int mid = left + (right - left) / 2;
// 对左半部分进行归并排序
mergeSortInternal(arr, temp, left, mid);
// 对右半部分进行归并排序
mergeSortInternal(arr, temp, mid + 1, right);
// 合并两个已排序的半部分
merge(arr, temp, left, mid, right);
}
/**
* 合并两个已排序的半部分
*
* @param arr 待合并的数组
* @param temp 临时数组
* @param left 左半部分的起始索引
* @param mid 中间索引
* @param right 右半部分的结束索引
*/
private static void merge(int[] arr, int[] temp, int left, int mid, int right) {
// 左边和右边的起始索引
int i = left;
int j = mid + 1;
// 合并元素到临时数组temp中
int t = 0;
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[t++] = arr[i++];
} else {
temp[t++] = arr[j++];
}
}
// 拷贝左边剩余的元素(如果有)
while (i <= mid) {
temp[t++] = arr[i++];
}
// 拷贝右边剩余的元素(如果有)
while (j <= right) {
temp[t++] = arr[j++];
}
// 将临时数组temp的元素拷贝回arr
t = 0;
int k = left;
while (k <= right) {
arr[k++] = temp[t++];
}
}
// 测试归并排序
public static void main(String[] args) {
int[] arr = {10, 7, 8, 9, 1, 5};
mergeSort(arr);
for (int num : arr) {
System.out.print(num + " ");
}
}
}
在这个示例中,mergeSort
方法是归并排序的入口点,它首先检查数组是否为空或长度小于2(此时无需排序)。然后,它创建一个临时数组,并调用 mergeSortInternal
方法来执行实际的排序操作。
mergeSortInternal
方法是递归地将数组分成两半,并对每一半进行排序。一旦两半都排好序,就调用 merge
方法将它们合并成一个有序的数组。
merge
方法负责合并两个已排序的半部分。它使用临时数组来存储合并的结果,然后将结果复制回原始数组。
在 main
方法中,我们创建了一个待排序的数组,并调用 mergeSort
方法来对其进行排序。然后,我们遍历排序后的数组并打印每个元素。
二分查找
public class BinarySearch {
/**
* 二分查找算法
*
* @param arr 已排序的数组
* @param left 查找范围的左边界(包含)
* @param right 查找范围的右边界(包含)
* @param target 要查找的目标值
* @return 如果找到目标值,返回其索引;否则返回-1
*/
public static int binarySearch(int[] arr, int left, int right, int target) {
// 检查边界条件
if (arr == null || left > right) {
return -1;
}
// 计算中间索引
int mid = left + (right - left) / 2;
// 如果中间元素就是目标值,直接返回其索引
if (arr[mid] == target) {
return mid;
}
// 如果目标值小于中间元素,则在左半部分继续查找
if (arr[mid] > target) {
return binarySearch(arr, left, mid - 1, target);
}
// 如果目标值大于中间元素,则在右半部分继续查找
return binarySearch(arr, mid + 1, right, target);
}
/**
* 测试二分查找算法
*
* @param args 命令行参数(未使用)
*/
public static void main(String[] args) {
int[] arr = {2, 3, 4, 10, 40}; // 示例数组,确保已排序
int target = 10; // 要查找的目标值
// 调用二分查找算法,并传入数组的起始索引0和结束索引(数组长度-1)
int result = binarySearch(arr, 0, arr.length - 1, target);
// 输出结果
if (result != -1) {
System.out.println("找到目标值 " + target + " 在索引 " + result);
} else {
System.out.println("未找到目标值 " + target);
}
}
}
在这段代码中,binarySearch
方法是二分查找算法的实现。它接受一个已排序的数组 arr
、查找范围的左右边界 left
和 right
,以及要查找的目标值 target
。方法首先检查边界条件,然后计算中间索引 mid
,并根据中间元素与目标值的大小关系,决定在左半部分还是右半部分继续查找。如果找到目标值,则返回其索引;如果未找到,则返回-1。
在 main
方法中,我们创建了一个示例数组 arr
,并指定了要查找的目标值 target
。然后,我们调用 binarySearch
方法,并传入数组的起始索引0和结束索引(数组长度-1)。最后,我们根据返回的结果输出相应的信息。