排序算法

1,插入排序:

(1)直接插入排序,将目标序列分成有序区和无序区,比较无序区第一个元素和有序区最后一个元素,如果前者比后者小,则将有序区后移一位,将无序区第一位插入有序区。算法实现:

public class Main{
    public static void main(String[] args){
        int[] a = {2,4,13,53,6,3,6};
        new Main().directInsert(a);
        for(int i:a)
        	System.out.print(i+" ");
    }
    
    void directInsert(int[] a){ 
    	for(int i=0; i<a.length-1; i++){
    		if(a[i+1]<a[i]){
    			int tmp = a[i+1];
    			int j = 0;
    			for(j=i; j>0&&a[j]>tmp; j--){
    				a[j+1] = a[j];
    			}
    			a[++j] = tmp;
    		}
    	}
    }
}

(2)希尔排序,跳跃式的直接插入排序。先设置初始增量,从目标序列种提取出以初始增量为间隔的子序列,用直接插入排序对该子序列进行排序。然后增量减1,重复上述步骤,直至增量减为0;算法实现:

public class Main{
    public static void main(String[] args){
        int[] a = {2,4,13,53,6,3,6};
        new Main().shellSort(a);
        for(int i:a)
        	System.out.print(i+" ");
    }
    
    void shellSort(int[] a){
    	int delta = a.length/3;
    	for(int d=delta; d>0; d--){
    		for(int i=d; i<a.length; i+=d){   
    			//当跳跃序列的无序区第一个小于有序区的最后一个,则执行插入操作
    			if(a[i]<a[i-d]){
    				int tmp = a[i];  
    				int j = 0;
    				for(j=i-d; j>0&&tmp<a[j]; j-=d){
    					a[j+d] = a[j];
    				}
    				a[j+=d] = tmp;
    			}
    		}
    	}
    }
}

2,选择排序:

(1)直接选择排序,先选中目标序列第0位,找到从第0位到最后一位中最小的一位,与第0位交换;选中第1位,找到从第1位到最后一位中最小的一位,与第1位交换;依次类推……算法实现:

public class Main{
    public static void main(String[] args){
        int[] a = {2,4,13,53,6,3,6};
        new Main().selectSort(a);
        for(int i:a)
        	System.out.print(i+" ");
    }
    
    void selectSort(int[] a){
    	int k=0;    	
    	for(int i=0; i<a.length-1; i++){
    		k = i;
    		for(int j=i+1; j<a.length; j++){
    			if(a[j]<a[k]) k = j;
    		}
    		if(k!=i){
	    		int tmp = a[i];
	    		a[i] = a[k];
	    		a[k] = tmp;
    		}
    	}    	
    }
}

(2)堆排序:堆是一种特殊的完全二叉树,可分为最大堆和最小堆。最大堆,父节点均大于子节点,从根节点到任意叶子节点的路径是降序的。最小堆,父节点均小于子节点,从根节点到任意叶子结点的路径是升序的。因此,最大堆的根节点存储的是最大值,最小堆的根节点存储的是最小值。创建最大堆的过程如下:从(n-1)/2位开始,两个指针k和j,k指向父节点,j指向子节点中的较大节点。如果子节点大于父节点,则将两者交换位置,交换之后要将k指向原子节点,j指向原子节点的子节点,重复上述判断。排序的过程是:依次对初始序列的0到limit位创建最大堆,此时最大值存储在data[0],将其与data[limit]交换,将limit减1,继续上述操作。算法实现:

public class Main{
    public static void main(String[] args){
        int[] a = {2,4,13,53,6,3,6};
        new Main().heapSort(a);
        for(int i:a)
        	System.out.print(i+" ");
    }
    
    void heapSort(int[] a){
    	for(int limit = a.length-1; limit>0; limit--){
    		createHeap(a,0,limit);
    		int tmp = a[0];
    		a[0] = a[limit];
    		a[limit] = tmp;
    	}
    }
    static void createHeap(int[] data, int low, int high){
    	for(int i=high/2; i>=0; i--){
    		int tmp = data[i];//将当前父节点保存起来,避免被覆盖
    		int k = i;//k指向父节点
    		int j = 2*k+1;//j指向子节点
    		while(j<=high){
    			if(j<high&&data[j]<data[j+1]) j++;//j指向两个子节点中较大的一个
    			if(data[k]<data[j]){//如果父节点小于较大的子节点,则将子节点移至父节点
    				data[k] = data[j];
    				k = j;//将k指向原子节点
    				j = 2*k+1;//将j指向原子结点的子节点
    			}else{
    				break;//如果父节点大于较大子节点,则无需任何操作
    			}
    		}
    		data[k] = tmp;//将父节点移至子节点,完成交换
    						
    	}
    }
}

3,交换排序

(1)冒泡排序:依次比较data[i]和data[i+1]的大小,如果data[i]>data[i+1],则两者交换,这样一趟下来的结果是,最大的值被移动到了数组的末位,然后对剩下的无序区继续进行冒泡排序,把次最大移动到倒数第二位。这样的排序操作最多要进行n-1趟。代码实现:

public class Main{
    public static void main(String[] args){
        int[] a = {2,4,13,53,6,3,6};
        new Main().bubbleSort(a);
        for(int i:a)
        	System.out.print(i+" ");
    }
    
    void bubbleSort(int[] a){
    	boolean flag;
    	for(int i=1; i<a.length; i++){//最多做n-1趟排序
    		flag = false;
    		for(int j=0; j<a.length-i; j++){
    			if(a[j+1]<a[j]){
    				int tmp = a[j];
    				a[j] = a[j+1];
    				a[j+1] = tmp;
    				flag = true;//发生了交换
    			}    			
    		}
    		if(!flag) break;//如果本趟没有发生交换,说明排序已经完成,可以提前结束
    	}
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值