/** 建立一个用于操作数组的工具类,其中包含着常见的对数组的操作函数如:排序,最值等 @author jepson @version v1.0 */ public class ArrayTool { /*该类中的方法都是静态的,所以该类是不需要创建对象的, 为了保证不让其它程序创建该类对象 可以将该类的构造函数私有化。 */ private ArrayTool(){} /** 对给定的整数数组进行直接插入排序 @param arr 接收一个元素类型为int的整数数组 */ public static void directInsertSort(int[] arr) //直接插入排序 { for (int i=1; i<arr.length; ++i) //第一个元素已经有序,所以从第二个元素开始 { int temp = arr[i]; //将要插入的元素暂存于temp临时变量中 int j = i-1; //j指向想要与待插入元素进行比较的第一个元素,也就是它左边的第一个元素 while (j>=0&&temp<arr[j]) //如果j>=0并且带插入元素比当前比较的元素小,就让该元素后移一位。 { arr[j+1]=arr[j]; //后移一位 --j; //j指向下一个需要比较的元素。 } arr[j+1]=temp; //找到了插入位置之后,将待插入元素放入其中。 } } /** 对给定的整数数组进行折半插入排序 @param arr 接收一个元素类型为int型的整数数组 */ public static void binaryInsertSort(int[] arr) //折半插入排序 { for (int i=1; i<arr.length; ++i) //第一个元素已经有序,所以从第二个元素开始 { int temp = arr[i]; //将要插入的元素暂存于temp临时变量中 int low = 0; //low指向待查找的有序序列的第一个元素的下标 int high = i-1; //high指向待查找的有序序列的最后一个元素的角标 while (low<=high) //low>high结束运行 { int mid = (low+high)/2; //mid指向中间位置。 if (temp<arr[mid]) //如果待插入元素小于中间位置的元素,那么就应该在左侧查找。 { high = mid-1; } else //如果待插入元素不小于中间位置的元素,那么就应该在右侧查找。 { low = mid +1; } }//while循环结束就表示找到了插入位置 for (int j=i-1;j>=low ;--j ) //有序序列包括插入位置在类的元素都应该后移一个位置 { arr[j+1] = arr[j]; //后移一个位置。 --j; //j指向下一个要移动的元素 } arr[low]=temp; //将待插入元素插入找到的位置。。 //arr[high+1]=temp; } } /** 对给定的整数数组进行希尔排序 @param arr 接收一个元素类型为int型的整数数组 */ public static void shellSort(int[] arr) //希尔排序 { for (int gap=arr.length/2;gap>=1 ;gap/=2 ) //设置增量,当增量<1的时候结束 { for (int i=gap;i<arr.length ;++i ) //这里开始实际就是直接插入排序 { int temp = arr[i]; int j=i-gap; while (j>=0&&temp<arr[j]) { arr[j+gap]=arr[j]; j=j-gap; } arr[j+gap] = temp; } } } /** 对给定的数组进行交换类的冒泡排序 @param arr 接收一个元素类型为int型的整数数组 */ public static void bubbleSort(int[] arr) //冒泡排序 { for (int i=1;i<arr.length ;++i ) //外层大循环为n-1圈。 { int flag=0; //每一次循环的时候让flag=0,冒泡排序结束的条件是一趟排序没有发生交换 for (int j=0;j<arr.length-i;++j ) //从第一个元素开始让第一个元素和第二元素比较,第二个元素和第三个元素比较 { if (arr[j]>arr[j+1]) //只要前面一个元素大于后面的元素就交换 { //int temp=arr[j]; //arr[j]=arr[j+1]; //arr[j+1]=temp; swap(arr,j,j+1); flag=1; //发生了交换就置falg=1; } } if (flag==0) //如果一趟中没有发生交换,说明就已经有序,结束运行,直接返回给调用函数继续执行 { return; } } } /** 对给定的数组进行交换类的快速排序 @param arr 接收一个元素类型为int型的整数数组 @param Left 接收要排序的数据的第一个元素的角标 @param Right 接收要排序的数据的最后一个元素的角标 */ public static void quickSort(int[] arr,int Left,int Right) //快速排序 { int i=Left; //i指向要排序的数列的最左边元素 int j=Right; //j指向要排序的数据的最右边元素 if (Left<Right) //只要区域元素不少于两个就执行 { int temp=arr[i]; //将轴心暂存于temp中。 while (i!=j) //i=j的时候停止循环 { while (j>i&&arr[j]>temp) //从右向左扫描,找到第一个不大于temp的元素结束 { --j; } if (j>i) //将这个元素放入i位置,并让i右移一个位置 { arr[i]=arr[j]; ++i; } while (i<j&&arr[i]<temp) //i从左向右扫描,找到第一个不小于temp的元素结束 { ++i; } if (i<j) //将这个元素放入ji位置,并让j左移一个位置 { arr[j]=arr[i]; --j; } } arr[i]=temp; //将轴心放入找到的位置。 quickSort(arr,Left,i-1); //递归处理轴心的左侧部分 quickSort(arr,i+1,Right); //递归处理轴心的右侧部分 } } /** 对给定的整数数组进行选择排序 @param arr 接收一个元素为int型的数组 */ public static void selectSort(int[] arr) { int j,k,temp; for (int i=0;i<arr.length ;++i ) { k=i; for (j=i; j<arr.length; ++j) { if (arr[j]<arr[k]) { k=j; } } //temp = arr[i]; //arr[i]=arr[k]; //arr[k]=temp; swap(arr,i,k); } } /** 对给定的整数数组进行堆排序 @param arr 接收一个元素为int型的数组 */ public static void heapSort(int[] arr) { for (int i=(arr.length-1)/2; i>=0;--i ) //构建初始堆 { sift(arr,i,arr.length-1); } for (int i=arr.length-1;i>0 ; --i) //让堆中的第一个元素和最后一个元素交换,并且对交换后的第一个位置的元素进行调整 { //int temp = arr[0]; //arr[0] = arr[i]; //arr[i] = arr[0]; swap(arr,0,i); sift(arr,0,i-1); } } private static void sift(int arr[] , int low,int high) //对low到high位置,low位置进行堆排序 { int i = low; //i指向要调整的元素 int j = 2*i+1; //指向左孩子 int temp = arr[i]; while (j<=high) //只要j>high就循环 { if (j<high&&arr[j]<arr[j+1]) //如果有右孩子 有孩子更大,就让j指向更大的孩子 { ++j; } if (temp<arr[j]) //如果孩子结点更大,就让最大的孩子放到双亲的位置上去。 { arr[i]=arr[j]; i=j; j=2*i+1; } else break; } arr[i]=temp; //将调整的元素放到最值的位置。 } /** 用于给数组进行元素的位置置换 @param arr 接收一个元素为int型的数组 @param a 要交换的元素的下标 @param b 要交换的元素的下标 */ private static void swap(int[] arr,int a, int b) { int temp; temp=arr[a]; arr[a]=arr[b]; arr[b]=temp; } /** 获取整数数组的最大值 @param arr 接收一个元素为int型的数组 @return 返回该数组的最大元素值 */ public static int getMax(int[] arr) { int max = arr[0]; for (int i=0;i<arr.length ; ++i) { if (max<arr[i]) { max = arr[i]; } } return max; } /** 获取整数数组的最小值 @param arr 接收一个元素为int型的数组 @return 返回该数组的最大元素值 */ public static int getMin(int[] arr) { int min = arr[0]; for (int i=0;i<arr.length ; ++i) { if (min>arr[i]) { min = arr[i]; } } return min; } /** 获取指定元素在指定数组中的角标 @param arr 接收一个元素为int型的数组 @param key 指定的元素 @return 该元素在数组中的坐标 */ public static int getIndex(int[] arr,int key) { for (int i=0;i<arr.length ;++i ) { if (arr[i]==key) { return i; } } return -1; } /** 使用二分查找(折半查找)获取指定元素在指定数组中的角标 @param arr 接收一个元素为int型的数组 @param key 指定的元素 @return 找到了返回该元素在数组中的坐标,没找到返回 “-插入点-1” */ public static int binarySearch(int[] arr,int key) //二分查找 { int low=0; //指向查找序列的第一个位置 int high=arr.length-1;//指向查找序列的最后一个位置 int mid; while (low<=high) //low>high的时候结束循环 { mid = (low+high)>>1; //mid指向中间位置 if (arr[mid]>key) //终于该查找元素,则在左侧部分查找 { high=mid-1; } else if (arr[mid]<key) //小于则在右侧部分查找 { low=mid+1; } else //找到了,就返回坐标 return mid; } return -low-1; //没有找到返回 -插入点-1 } /** 将int型数组转换成字符串。格式:[e1,e2,......] @param arr 接收一个元素为int型的数组 @return 返回该数组的字符串表现形式 */ public static String arrayToString(int[] arr) { String str = "["; for (int i=0;i<arr.length ;++i ) { if (i!=arr.length-1) { str = str +arr[i]+"," ; } else { str = str + arr[i]+"]"; } } return str; } /** 将int型数组转换成字符串。格式:[e(n),e(n-1),......,e2,e1] @param arr 接收一个元素为int型的数组 @return 返回该数组的字符串表现形式 */ public static String arrayReverseToString(int[] arr) { String str = "["; for (int i=arr.length-1;i>=0 ;--i ) { if (i!=0) { str = str +arr[i]+"," ; } else { str = str + arr[i]+"]"; } } return str; } }