/**
建立一个用于操作数组的工具类,其中包含着常见的对数组的操作函数如:排序,最值等
@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;
}
}