package practice5;
public class array {
//直接插入排序
public static void insertsort(int[]table){
for(int i=1;i<table.length;i++){//n-1趟扫描,每趟将table[i]插入到它前面已排序的子序列中
int temp=table[i],j;
for(j=i-1;j>-1&&temp<table[j];j--){ //将前面大于temp的元素向后移动
table[j+1]=table[j];
}
table[j+1]=temp; //temp值到达插入位置
}
}
//希尔排序
public static void shellsort(int[] table){
for(int delta=table.length/2;delta>0;delta/=2){ //控制增量,增量减半,若干趟扫描
for(int i=delta;i<table.length;i++){ //一趟中若干组,每个元素在自己组内进行直接插入排序
int temp=table[i]; //当前待插入元素
int j=i-delta; //组内两个元素之间相距delta远
while(j>-1&&temp<table[j]){ //一组中大于temp的元素向后移
table[j+delta]=table[j];
j-=delta; //继续与前面元素比较
}
table[j+delta]=temp; //插入元素位置
}
}
}
//冒泡排序
public static void bubblesort(int[]table){
for(int i=1;i<table.length;i++) //进行n-1趟排序
for(int j=0;j<table.length-i;j++){ //进行一次比较,交换
if(table[j]>table[j+1]){
int temp=table[j];
table[j]=table[j+1];
table[j+1]=temp;
}
}
}
//快速排序
public static void quicksort(int[] table){
quicksort(table,0,table.length-1);
}
public static void quicksort(int[]table,int low,int high){
if(low<high){ //如果序列有效,用于结束递归时使用
int i=low,j=high;
int vot=table[i]; //第一个值作为基准值
while(i!=j){
while(i<j&&vot<table[j]) //从后向前寻找比vot小的值
j--; //若找不到则继续向前寻找,若找到则跳出循环
if(i<j){
table[i]=table[j]; //将比vot小的值向前移动
i++;
}
while(i<j&&vot>table[i]) //从前往后寻找比vot大的值
i++; //若找不到则继续向后寻找,若找到则跳出循环
if(i<j){
table[j]=table[i]; //将比vot大的值向后移动
j--;
}
}
table[i]=vot; //基准值的最终位置
quicksort(table,low,j-1); //前端子序列再排序
quicksort(table,i+1,high); //后端子序列再排序
}
}
//直接选择排序
public static void selectsort(int[] table){
for(int i=0;i<table.length-1;i++){ //n-1趟排序每趟从table[i]开始的子序列中寻找元素
int min=i; //设第i个数据元素最小
for(int j=i+1;j<table.length;j++) //在子序列中查找最小值
if(table[j]<table[min])
min=j; //记住最小元素的下标
if(min!=i){ //将本趟最小元素交换到前面
int temp=table[i];
table[i]=table[min];
table[min]=temp;
}
}
}
//堆排序 ,将以low为根的子树调整成最小堆,low,high是序列的上下界
public static void sift(int[]table,int low,int high){
int i=low; //子树的根
int j=2*i+1; //j为i结点的左孩子
int temp=table[i]; //获得第i个元素的值
while(j<=high){ //沿较小值孩子结点向下筛选
if(j<high&&table[j]>table[j+1]) //如果左孩子结点大于右孩子结点
j++;
if(temp>table[j]){ //如果父母节点大于孩子结点
table[i]=table[j]; //孩子结点中较小值上移
i=j; //i,j向下一层
j=2*i+1;
}
else
j=high+1; //如果j>high,退出循环
}
table[i]=temp; //当前子树的原根值调整后的位置
}
public static void heapsort(int[]table){
int n=table.length;
for(int j=n/2-1;j>=0;j--) //创建最小堆
sift(table,j,n-1);
for(int j=n-1;j>0;j--){ //每趟将最小值交换到后面,再调整成堆
int temp=table[0];
table[0]=table[j];
table[j]=temp;
sift(table,0,j-1);
}
}
//归并排序
public static void merge(int[]x,int[]y,int m,int r,int n){ //一次归并
int i=m,k=m,j=r;
while(i<r&&j<r+n&&j<x.length){ //将x中两个相邻子序列归并到y中
if(x[i]<x[j]) // 较小值复制到y中
y[k++]=x[i++];
else
y[k++]=x[j++];
}
while(i<r) //将前一个子序列剩余元素复制到y中
y[k++]=x[i++];
while(j<r+n&&j<x.length) //将后一个子序列剩余元素复制到y中
y[k++]=x[j++];
}
public static void mergepass(int[]x,int[]y,int n){ //一趟归并
int i=0;
while(i+2*n<x.length){ //一趟归并中进行归并的次数
merge(x,y,i,i+n,n);
i+=2*n;
}
if(i+n<x.length) //归并两个长度不等的有序表
merge(x,y,i,i+n,n);
else
for(int j=i;j<x.length;j++) //将x剩余元素复制到y中
y[j]=x[j];
}
public static void mergesort(int[] x){
int n=1; //定义子序列长度n为1
int[]y=new int[x.length]; //y数组长度同x数组
while(n<x.length){ //子序列长度小于x
mergepass(x,y,n); //一趟归并,将x数组中各子序列归并到y中
n*=2; //子序列长度加倍
if(n<=x.length){
mergepass(y,x,n); //将y数组中各子序列再归并到x中
n*=2;
}
}
}
public static void main(String[] args){
array a=new array();
int[] table={10,9,5,8,16,7,90,22,23};
System.out.println("归并排序");
a.mergesort(table);
for(int i=0;i<table.length;i++)
System.out.print(table[i]+" ");
}
}