数组排序问题
1.冒泡排序算法
冒泡排序(Bubble Sort) - 通过不断交换相邻元素的位置,逐步将最大或最小的元素"冒泡"到序列的两端。
思路:
冒泡排序算法的一趟原理如下:
相邻元素进行两两比较,如果前者大于后者,则交换,否则不变。
每一趟依次向后进行第1步,直到最后一个元素。
经过一趟的依次比较后的结果是,最后一个数是本趟比较中最大的数。所谓大数 "沉入水底" ,轻的气泡 "向上冒泡"。
继续重复1、2、3 步骤。每趟只比较到上一步剩下的部分即可(除去最后的已经 "沉到底部" 的元素)。
详细步骤如下:
冒泡排序 :比较次数(内层循环) 和 趟数(外层循环)
7 3 2 1 9\]:
每一趟 找出最大值放到最后
* 总结规律:i\ 具体代码如下: 选择排序(Selection Sort) - 每一轮在剩余未排序的元素中找到最小(或最大)的元素,放到已排序部分的末尾 思路: 选择排序每趟选择一个固定位置上的元素,向后逐一和此位置上的数进行比较,如果小于此位置上的数,则交换。 一趟结束后,此位置上的数就是当前排序序列中最小的元素了。 重复上面的步骤即可排序成功。 步骤举例: 3,6,9,2,7\] i 和 j 比较+
插入排序(Insertion Sort) - 将每个元素按其正确位置插入已排序的部分,保持已排序部分始终有序 思路: 插入排序思路: 从第二个位置上开始,每次选择一个位置上元素,和前面的数逐一比较,如果小于前面的数,则前面数后移,直到大于前面的数,则停止移动,插入位置。这样每趟走完之后,前面的已经插入的序列一定是有序。 就如生活中的起扑克牌一样,每起一张都会插入手中,但是插入后,手中的牌一直是有序的。 步骤举例 快速排序(Quick Sort) - 使用分治策略,选取一个基准元素,将数组划分为两部分,左边的元素都小于基准,右边的元素都大于基准,然后递归地对左右两边进行快速排序 思路: 需要使用到递归 每次选择一个元素,通过一趟的过程,前后比较,从而找到自己的合适位置,即此位置前的都比次数小,此位置之后的,都比次数大。 然后再对已经分割的两部分,重复递归使用相同的方法来找每个数的位置。递归嵌套即可完成排序。 步骤举例 希尔排序(Shell Sort) - 是插入排序的一种优化版本,通过定义一个间隔序列来分组元素,使得不同组内的元素相对较远,从而减少整体的交换次数。 以下是一个简单的 Java 语言实现希尔排序的示例。在这个例子中,我将展示一种基于经典希尔排序算法思想的实现,其中采用的是Hibbard增量序列(即增量每次都为前一次的一半,直到增量为1)。 这段代码首先设置了一个初始步长(
public static void maopao(){
int[] arr = {7,3,12,1,0};
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-i-1; j++) {
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
2.选择排序算法:
/**
* 总结:
* i--0~length-1
* j--i+1~length-1
* 比较:
* i和j
*/
public static void selorder(int[] arr){
// int[] arr = {3,6,9,2,7};
for (int i = 0; i < arr.length-1; i++) {
for (int j = i+1; j <= arr.length-1; j++) {
if(arr[i]>arr[j]){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
//System.out.println(Arrays.toString(arr));
}
3.插入排序算法:
public static void insertOrder() {
int[] arr = {9,8,7,6,5,4,3,2};
for (int i = 1; i < arr.length; i++) {
int insert = arr[i];
for (int j = i; j > 0; j--) {
//前面的数大于已经选择插入的数,则后移
if(arr[j-1]>insert) {
arr[j] = arr[j-1];
arr[j-1] = insert;
}else {
arr[j] = insert;
break;
}
}
}
System.out.println("排序后:"+Arrays.toString(arr));
}
4.快速排序算法
package com;
import java.util.Arrays;
public class QuickSort {
public static void quickSort(int[] arr,int low,int high){
int i,j,temp,t;
if(low>high){
return;
}
i=low;
j=high;
//temp就是基准位
temp = arr[low];
while (i<j) {
//先看右边,依次往左递减
while (temp<=arr[j]&&i<j) {
j--;
}
//再看左边,依次往右递增
while (temp>=arr[i]&&i<j) {
i++;
}
//如果满足条件则交换
if (i<j) {
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
//最后将基准为与i和j相等位置的数字交换
arr[low] = arr[i];
arr[i] = temp;
//递归调用左半数组
quickSort(arr, low, j-1);
//递归调用右半数组
quickSort(arr, j+1, high);
}
public static void main(String[] args){
int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
quickSort(arr, 0, arr.length-1);
System.out.println(Arrays.toString(arr));
}
}
5. 希尔排序
public class ShellSort {
/**
* 希尔排序(Hibbard增量序列)
*
* @param arr 待排序的整数数组
*/
public static void shellSort(int[] arr) {
// 获取数组长度
int n = arr.length;
// 开始时设定一个较大的步长(通常是n/2,这里简化为直接使用常量)
int gap = n / 2;
while (gap > 0) {
// 按照当前步长进行插入排序
for (int i = gap; i < n; i++) {
// 将arr[i]插入到arr[i-gap], arr[i-2*gap]...已经排序好的序列中
int temp = arr[i];
int j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
// 插入元素
arr[j] = temp;
}
// 缩小增量
gap /= 2; // 或者 gap = (gap == 2) ? 1 : gap / 2; 这种方式可以防止gap变为0
}
}
public static void main(String[] args) {
int[] arr = {5, 1, 7, 3, 1, 6, 9, 4};
shellSort(arr);
// 输出排序后的数组
for (int num : arr) {
System.out.print(num + " ");
}
}
}
gap
),然后在每一次循环中,都会对所有按照步长分组的子序列进行插入排序。随着步长逐渐减小至1,整个数组就被分成了越来越多的小组,最终实现全局有序。当步长减小到1时,实际上就是执行了一次完整的插入排序,此时数组已经是有序的了。