/**
* 排序
* 平均时间复杂度:
* nLogn:快排、堆排序、归并排序 (递归)
* d(n+r):基数排序
* n^2:其它
* 空间复杂度:
* Logn:快排 (递归)
* n:归并排序 (一个额外数组)
* r:基数排序
* 1:其它
*
* 稳定性:
* 不稳定:希尔、快排、简单选择排序、堆排序
*/
public class Sort {
private static int[] arr=new int[20]; //数组大小
public static void main(String[] args) {
Sort sort=new Sort();
sort.setArray();
sort.getArray();
//升序排序
// sort.sort1();
// sort.sort4();
// sort.sort5(0,arr.length-1);
// sort.sort6();
sort.sort7(arr.length);
// sort.sort8(0,arr.length-1);
sort.getArray();
}
//生成20个 -100~100 随机数
public void setArray(){
for (int i=0;i<arr.length;i++){
int a= (int) (Math.random()*100);
int flag=(int) (Math.random()*2);//随机数0 1(0负数,1正数)
if(flag==0){
a=-a;
}
arr[i]=a;
}
}
//输出数组
public void getArray(){
for(int a:arr){
System.out.print(a+"\t");
}
System.out.println();
}
//1 直接插入排序: 最后i有序,前n-i个元素无序,将最后一个无序元素n-i-1插入有序序列中
public void sort1(){
int n = arr.length;
//最后i个有序
for(int i=1;i<n;i++){
//最后一个无序元素,与后面的有序序列比较
int k=n-i-1;
//计算插入位置j
int j;
boolean flag=false;
for(j=n-i;j<n;j++){
if(arr[k]>arr[j]){
flag=true;//需要移动元素
}
if(flag && arr[k]<=arr[j]){
break;
}
}
if(flag){//插入元素:k处插入到j处,(k,j]前移
j--;
int t=arr[k];
for(int z=k+1;z<=j;z++){
arr[z-1]=arr[z];
}
arr[j]=t;
}
}
}
//2 折半插入排序
public void sort2(){
}
//3 希尔排序
public void sort3(){
}
//4 (交换)冒泡排序:比较相邻的两个数,大的放后面(从前往后比,一轮下来,最后是最大值)
public void sort4(){
int n=arr.length;
for(int i=0;i<n-1;i++){
for (int j=0;j<n-1-i;j++){
if(arr[j+1]<arr[j]){
int t=arr[j+1];
arr[j+1]=arr[j];
arr[j]=t;
}
}
}
}
//5 (交换)快排
// 5.1 low为基准数t,开始high比较 high>t则high--,否则high值赋给low;开始low比较 low<t则low++,否则low值赋给high;直到low=high结束一次循环
// 5.2 递归,基准数t左边、右边分别进行5.1
public void sort5(int low,int high){
if(low<high){
int t=partition(low,high);
sort5(low,t-1);
sort5(t+1,high);
}
}
private int partition(int low,int high){//一轮快排
int t=arr[low];
while(low<high){
while(low<high && arr[high]>=t) high--;
arr[low]=arr[high];
while(low<high && arr[low]<=t) low++;
arr[high]=arr[low];
}
arr[low]=t;
return low;
}
//6 简单选择排序:以第一个为基准,和后面的比较,选择最小的,记录下标,和第一个交换
public void sort6(){
int n=arr.length;
for(int i=0;i<n-1;i++){
int minArr=arr[i];
int min=i;
for(int j=i+1;j<=n-1;j++){
if(arr[j]<minArr){
minArr=arr[j];
min=j;
}
}
if(min!=i){
int t=arr[i];
arr[i]=arr[min];
arr[min]=t;
}
}
}
//7 堆排序:制作大根堆,然后交换根和最后一个元素,逻辑上删除最后一个元素,再次制作大根堆
public void sort7(int n){//n 剩余长度
//从最后一个非叶子节点开始,构建大根堆
if(n<=1){//长度为1,结束递归
return;
}
for(int i=n/2-1;i>=0;i--){
heap(i,n);
}
//一轮结束,交换根和最后一个
int t=arr[n-1];
arr[n-1]=arr[0];
arr[0]=t;
//递归
sort7(--n);
}
private void heap(int k,int n){//大根堆调整(k 要排序的根下标,n剩余长度)
int leaf=2*k+1;//左叶子下标
while(leaf<n){
//取叶子节点最大值
if(leaf+1<n && arr[leaf+1]>arr[leaf]){//有右叶子,并且右叶子数大于左叶子
leaf++;
}
//叶子节点大,交换
if(arr[leaf]>arr[k]){
int t=arr[leaf];
arr[leaf]=arr[k];
arr[k]=t;
k=leaf;
leaf=2*k+1;
}else{
break;
}
}
}
//8 归并排序:一个元素是一组,组内排序;相邻两个组归并;(左右两边分别归并,再归并左右)
// 8.1 归并:新建一个数组,相邻两个组都从首开始比较,小的放入新数组;最后把新数组复制到原来位置
public void sort8(int low,int high){
if(low<high){
int mid=(low+high)/2;
sort8(low,mid);
sort8(mid+1,high);
merge(low,high);
}
}
private void merge(int low,int high){//归并两个相邻数组
int k=0;//新数组下标
int[] arrNew=new int[high-low+1];
int mid=(low+high)/2;
int i=low;
int j=mid+1;
while(i<=mid && j<=high){
if(arr[i]<arr[j]){
arrNew[k++]=arr[i++];
}else{
arrNew[k++]=arr[j++];
}
}
//剩余部分
while(i<=mid){
arrNew[k++]=arr[i++];
}
while(j<=high){
arrNew[k++]=arr[j++];
}
//交换
for(int z=0;z<arrNew.length;z++){
arr[low++]=arrNew[z];
}
}
//9 基数排序
public void sort9(){
}
}
排序java代码:直接插入排序、简单选择排序、冒泡排序、快排、堆排序、归并排序
猜你喜欢
转载自blog.csdn.net/poppy_rain/article/details/104429724
今日推荐
周排行