public class Test
{
public static void main(String[] args)
{
int array1[]={11,2,3,4,5,66,7,120,77,8,88,33,22,55};
// showBycharu(array1);
// quickSort(array1,0,array1.length-1);
// heapSort(array1);
// mergeSort(array1);
jishuSort(array1,3);
showArray(array1);
}
public static void showBycharu(int arr[])
{
//插入排序 递增排序 数组中交换位置
for (int i = 1; i < arr.length; i++)
{
int j = i; //到j的位置都会到之前的数组中找到位置
while (j > 0 && arr[j] < arr[j - 1]) { //不断按照顺序增加一个数,然后在已有的有序数组中插入到合适的位置
swap(arr,j,j-1);
j--;//比较到arr[0]时候停止
}
}
}
public static void showMaopao(int arr[])
{
//冒泡排序
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])
{
swap(arr,j,j+1);
}
}
}
}
public static void showCheck(int []arr)
{
//选择排序 从小到大,不断找出最小的,然后按照循环的位置第一次找出第一小,第二次找出第二小
for(int i=0;i<arr.length-1;i++) //最后一次循环不用做
{
int min=i; //最小从零开始
for(int j=i+1;j<arr.length;j++) //第一此循环 找出最小的哪个位置,然后和0位置交换,第二次找出第二小的和1位置交换
{
if(arr[j]<arr[min]) //不断选择出最小的然后放在后面
min=j;
}
if(min!=i)//这里如果i就是最小,不变,否则交换
{
swap(arr,min,i);
}
}
}
public static void showXIER(int []arr)
{
//希尔排序
for(int gap=arr.length/2;gap>0;gap/=2)//逐渐缩小gap 按照初二的速度 长度12 6 3 2 1
{
for(int i=gap;i<arr.length;i++) //6 7 8 9 10 11 12
{
//从第gap位置 逐个对所在组进行插入操作
int j=i;
while(j-gap>=0&&arr[j]<arr[j-gap]) // 6-6 7-6 8-2...... // 3--0 4--1 5-2 .... // 2--0 3--1.......// 1-0 2-1 3-2 .....
{
swap(arr,j,j-gap);
j-=gap;
}
}
}
}
public static void quickSort(int arr[],int low,int high)
{
//快速排序
int l=low;
int h=high;
int povit=arr[low];
while(l<h)
{
while(l<h&&arr[h]>=povit)
{
h--; //从右边向左边递减,直到找到比povit小的
}
if(l<h)
{//循环停止之后, l仍然小于h 就是arr[h]<povit 所以 交换 povit 和 arr[h]的值
swap(arr,h,l);
l++;
}
while(l<h&&arr[l]<=povit)// 从左边逐渐增加,比较左边比povit 大的
{
l++;
}
if(l<h)
{
//停止循环之后 有个值比povit大 povit 的值的位置是h 所以交换h 和i 的位置的值
swap(arr,l,h);
h--;
}
}
//当 l和h相等时候停止 因为两个相等之后: pivot值的左边都是比他小,而右边都是比他大的数
if(l>low)// i++ 后 对 i后面的排序
{
quickSort(arr,low,l-1);
}
if(h<high) // h-- 后对 i+1 到high的序列排序
{
quickSort(arr,l+1,high);
}
}
public static void heapSort(int arr[])
{
//堆排序
/* 1,首先构造堆 也就是父节点永远大于 (或者小于)子节点的二叉树
2.将对顶元素放到最后
3.继续构造堆,然后放到末尾 循环直至有序
*/
//1 构建大顶堆
for(int i=arr.length/2-1;i>=0;i--)
{
adjustHeap(arr,i,arr.length);
}
//2 调整堆结构,并接环对顶和末尾元素
for(int j=arr.length-1;j>0;j--)
{
swap(arr,0,j);//将最大的放到最后,然后调整大顶堆
adjustHeap(arr,0,j);
}
}
/**
* @arr 数组
* @i 当前堆的最后一个非叶子节点,也就是arr.length/2-1 的位置
* 这相当与找到一个节点的最大值,配合上面的循环,直到找到最终的堆结构
*/
public static void adjustHeap(int arr[],int i,int length)
{
//调整大顶堆,在大顶堆已经构建完成的基础上
int temp=arr[i]; //获取到子节点的位置的值 其第一个子节点的位置是i*2+1,然后每次都是子节点递增
for(int k=i*2+1;k<length;k=k*2+1)
{ //从i的左子节点开始,也就是2i+1处
if(k+1<length&&arr[k]<arr[k+1])
{
//如果当前节点的下一个节点存在,并且当前节点值小于下一个节点 转移到下一个节点
k++;
}
if(arr[k]>temp)
{
//找到两个节点中最大的,然后把值赋给父节点
arr[i]=arr[k];
i=k; //把i的值变成k,
}else
{
break;
}
}
arr[i]=temp;//然后对最终这个节点赋值
}
public static void mergeSort(int arr[])
{
//归并排序
int temp[]=new int[arr.length];
mergeSort(arr,0,arr.length-1,temp);
}
private 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);
}
}
private static void merge(int arr[],int left,int mid,int right,int temp[])
{
int i=left;
int j=mid+1;
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++];
}
t=0;
while(left<=right)
{
arr[left++]=temp[t++];
}
}
/**
*@d 表示最大数有多少位
*/
public static void jishuSort(int arr[],int d)
{
//基数排序
int k=0;
int n=1;
int m=1;
int [][]temp=new int[10][arr.length];//数组的第一维表示可能的余数0-9 [[],[],[],[],[],[],[],[],[],[]];
int[] order=new int[10];//数组orderp[i]用来表示该位是i的数的个数,因为temp会有重复的,而order表示的是当此循环有效
while(m<=d)
{
for(int i=0;i<arr.length;i++)
{
int lsd=(arr[i]/n)%10;//其个位、十位、百位、千位依次这样计算:n/1%10,n/10%10,n/100%10,n/1000%10 找出的个位数
temp[lsd][order[lsd]]=arr[i];//temp[个位..十位..百位][]
order[lsd]++;
}
for(int i=0;i<10;i++)//第一次循环完毕将按照个位的数值进行排序,第二次在第一次基础上进行十位的排序
{
if(order[i]!=0)//所以如果有的数上次没有被替代掉,下一次就不会被算入新的序列
{
for(int j=0;j<order[i];j++)
{
arr[k]=temp[i][j];
k++;
}
}
order[i]=0;
}
n*=10;
k=0;
m++;
}
}
public static void swap(int arr[],int a,int b)
{
//交换数组中,两个下标的值的位置
arr[a] = arr[a]+arr[b];
arr[b] = arr[a]-arr[b];
arr[a] = arr[a]-arr[b];
}
public static void showArray(int array[]){
//打印数组
for(Integer i:array)
{
System.out.println(i);
}
}
}