注意:
1.数组输出:使用tostring方法
Arrays.toString(arr)
2.某方法执行的时间:
long l1 = System.currentTimeMillis();
shellSort(arr1);
long l2 = System.currentTimeMillis();
冒泡排序
相邻两个值比较,较大的数放后面
//冒泡排序:相邻两个值比较,较大的数放后面
public static void bublleSort(int arr[]){
boolean flag=false;
for (int j=1;j<arr.length;j++){
for (int i=1;i<arr.length-j+1;i++)//i在往后移,因此是数字大的不断后移,所以第一次结束,最大数在最后面
if (arr[i]<arr[i-1]) {
flag=true;
arr[i] = arr[i] + arr[i - 1];
arr[i-1]=arr[i]-arr[i-1];
arr[i]=arr[i]-arr[i-1];
}
if (flag==false)//优化:一次交换都没发生,说明已经排序完成,直接结束循环
break;
}
}
选择排序
循环一次找出最小的,并放在前面
//选择排序:循环一次找出最小的,并放在前面
public static void selectSort(int arr[]){
for (int i=0;i<arr.length-1;i++){
int min=arr[i];
int temp=i;
for (int j=i+1;j<arr.length;j++){//找出最小的,并保存值与脚标
if (arr[j]<min){
min=arr[j];
temp=j;
}
}
//将最小的与arr[i]交换
arr[temp]=arr[i];
arr[i]=min;
}
}
插入排序
数组分成一个有序表和一个无序表,无序表的第一位和有序表进行比较再插入
//插入排序:数组分成一个有序表和一个无序表,无序表的第一位和有序表进行比较再插入
//无序表的第一个数,对有序表从后往前依次进行插入
// 无序表的第一个a取出:先与有序表最后一个b比,若a<b则将b后移;
// 再与有序表倒数第二个比,若a小则再后移……至a比某数大,将a放入空格中
public static void insertSort1(int arr[]){
for (int i=1;i<arr.length;i++){
int key=arr[i];
int j=i-1;
while (j>=0&& key<arr[j]){
arr[j+1]=arr[j];
j--;
}
arr[j+1]=key;
}
}
希尔排序
//希尔排序:先分组(即确定增量),再对组内进行插入排序
public static void shellSort(int arr[]){
int key,k,j;
for (int gap=arr.length/2;gap>0;gap/=2){//先分组
for (int i=gap;i<arr.length;i++){//对每一组进行插入排序,i=gap:每一组的第二个元素,因为第一个元素有序
key=arr[i];//需要插入的元素
for (j=i-gap;j>=0&& key<arr[j];j-=gap)//j:有序表最后一个值
arr[j+gap]=arr[j];
arr[j+gap]=key;//注意j-=gap执行后再进入for循环的判断条件
}
}
}
快速排序:
先确定一个基准值,排序结束后比基准值小的放在基准值左边,比基准值大的放在基准值右边。
使用arr[left]作为基准值
public static void quickSort1(int left,int right,int arr[]){
//递归结束条件:
// 当左边排好,则l=r=left=0,再次调用方法将出现left=0,right=-1
//当右边排好,则l=r=right=arr.length-1,再次调用方法将出现left=arr.length,right=arr.length-1
if (left>right)
return;
//定义变量保存基准数
int l=left;
int r=right;
int pivot=arr[left];
while (l!=r){
//一定从右边开始检索,保证停下时的数<基准数
while (arr[r]>=pivot&&l<r)//若检索>=基准数,则继续检索
r--;
while (arr[l]<=pivot&&l<r)//若检索<=基准数,则继续检索
l++;
//两边都找到了待交换的值,或是l=r
int temp=arr[r];
arr[r]=arr[l];
arr[l]=temp;
}
//l与r相遇
arr[left]=arr[r];
arr[r]=pivot;
//递归
quickSort1(left,l-1,arr);
quickSort(r+1,right,arr);
}
归并排序:
将数据不断分为两部分,直至只有一个数据
再两两合并,排成有序数列;合并后再与另一合并的有序数列合并……至合并完成
public static void mergeSort(int[]arr,int left,int right,int[]temp){
if (left<right){
int mid=(left+right)/2;
//向左递归进行分解
mergeSort(arr,left,mid,temp);
//向右递归进行分解
mergeSort(arr,mid+1,right,temp);
//合并
merge(arr,left,mid,right,temp);
}
}
/**
*合并
* @param arr 需要排序的原始数组
* @param left 左边有序序列的初始索引
* @param mid 中间索引
* @param right 右边索引
* @param temp 中转的数组
*/
public static void merge(int[]arr, int left, int mid, int right, int[]temp){
int i=left;//左边有序数列的初始索引
int j=mid+1;//右边有序数组的初始索引
int t=left;//temp数组的指针
//先把左右两边(有序)数据填充到temp数组,直至有一边处理完成,再把另一边填充
while (i<=mid&&j<=right){
if (arr[i]<=arr[j]){
temp[t]=arr[i];
t++;
i++;
}
else{
temp[t]=arr[j];
t++;
j++;
}
}
while (i<=mid){//左边还没处理完
temp[t]=arr[i];
t++;
i++;
}
while (j<=right){//右边的没处理完
temp[t]=arr[j];
t++;
j++;
}
//合并到原数组
while (left<=right){
arr[left]=temp[left];
System.out.print(arr[left]);//输出每次合并的结果
left++;
}
System.out.println();
}
基数排序:
十个桶对应0-9十个数字,每个桶内都是一个数组存放数据。
第一轮按个位放到桶内,第二轮按十位,第三轮按百位……
public static void radixSort(int arr[]){
int [][] bucket=new int[10][arr.length];
int [] bucketElementCounts=new int[10];//记录每个桶中的数据个数
int i=0;//循环次数
while (true){
//根据个/十/百位……的数字将数据放入桶中
for (int j=0; j<arr.length;j++){
int digitOfElement = (int) (arr[j]/(Math.pow(10,i))%10);//digitOfElement为桶号
bucket[digitOfElement][bucketElementCounts[digitOfElement]] =arr[j];//将数据放入桶中
bucketElementCounts[digitOfElement]++;
}
i++;
//循环结束条件
if (bucketElementCounts[0]==arr.length)
break;
//桶内的数据放入arr[]中
int index=0;
for (int k=0;k<10;k++){
for (int l=0;l<bucketElementCounts[k];l++){
arr[index]=bucket[k][l];
index++;
}
bucketElementCounts[k]=0;//第一轮结束,把bucketElementCounts[]清零
}
}
}