java 排序

java实现八大排序

package com.demo01;

import java.util.Arrays;
import java.util.Scanner;

public class Array {

	/*
	 *  冒泡排序冒泡排序:
	 *  比较相邻的元素。两两对比,如果第一个比第二个数大,就交换位置
	 *  走第一轮会得到一个最大值/最小值。
	 *  n个数,排好序需要n轮
	 */ 
	public static void sortBubbling(int[] arr){
		for(int i=0; i<arr.length; i++){
			for(int j =i ;j<arr.length; j++){
				if(arr[i] > arr[j]){
					int temp = arr[i];
					arr[i] = arr[j];
					arr[j] = temp;
				}
			}
		}
		System.out.print("排序后的数组:");
		for(int i=0; i<arr.length;i++){
			System.out.print(arr[i]+",");
		}
	}
	/*
	 * 快速排序:
	 * 通过一趟排序将待排序记录分割成独立的两部分,
	 * 其中一部分记录的关键字均比另一部分关键字小,
	 * 则分别对这两部分继续进行排序,直到整个序列有序
	 * 把整个序列看做一个数组,把第零个位置看做中轴,和最后一个比,
	 * 如果比它小交换,比它大不做任何处理;
	 * 交换了以后再和小的那端比,比它小不交换,比他大交换。
	 * 这样循环往复,一趟排序完成,左边就是比中轴小的,
	 * 右边就是比中轴大的,然后再用分治法,分别对这两个独立的数组进行排序。
	 */
	   public static int getMiddle(int[] numbers, int low,int high){
	        int temp = numbers[low]; //数组的第一个作为中轴
	        while(low < high){
	        	while(low < high && numbers[high] >= temp){
	        		high--;
	        	}
	        	numbers[low] = numbers[high];//比中轴小的记录移到低端
	        	while(low < high && numbers[low] < temp){
	        		low++;
	        	}
	        	numbers[high] = numbers[low] ; //比中轴大的记录移到高端
	        }
	        numbers[low] = temp ; //中轴记录到尾
	        return low ; // 返回中轴的位置
	    }
	    public static void quickSort(int[] numbers,int low,int high){
	        if(low < high){
	        	int middle = getMiddle(numbers,low,high); //将numbers数组进行一分为二
	        	quickSort(numbers, low, middle-1);   //对低字段表进行递归排序
	        	quickSort(numbers, middle+1, high); //对高字段表进行递归排序
	        }
	    }
	    public static void quick(int[] numbers){
	        if(numbers.length > 0){   //查看数组是否为空
	        	quickSort(numbers, 0, numbers.length-1);
	        }
	    }
	    
	    /*
	     * 选择排序:
	     * 在一组数中,选出最小的一个数与第一个位置交换。
	     * 在剩下的数中重复上一步
	     */
	    public static void selectSort(int[] numbers){
		    int size = numbers.length; //数组长度
		    int temp = 0 ; //中间变量
		    for(int i = 0 ; i < size ; i++){
		        int k = i;   //待确定的位置
		        //选择出应该在第i个位置的数
		        for(int j = size -1 ; j > i ; j--){
			        if(numbers[j] < numbers[k]){
			            k = j;
			        }
		        }
		        //交换两个数
		        temp = numbers[i];
		        numbers[i] = numbers[k];
		        numbers[k] = temp;
		    }
	    }
	    /*
	     * 插入排序:
	     * 一组数,按其顺序码大小插入到前面已经排序的字序列的合适位置
	     * (从后向前找到合适位置后),直到全部插入排序完为止。
	     * 时间复杂度:O(n^2).
	     */
	    public static void insertSort(int[] numbers){
		    int size = numbers.length;
		    int temp = 0 ;
		    int j =  0;
		    for(int i = 0 ; i < size ; i++){
		        temp = numbers[i];
		        //假如temp比前面的值小,则将前面的值后移
		        for(j = i ; j > 0 && temp < numbers[j-1] ; j --){
		        	numbers[j] = numbers[j-1];
		        }
		        numbers[j] = temp;
		    }
	    }
	    
	    /*
	     * 希尔排序:
	     * 将序列分割成为若干子序列分别进行直接插入排序,
	     * 待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
	     * 拿数组5, 2, 8, 9, 1, 3,4来说,数组长度为7,当increment为7/2=3时,数组分为两个序列
	     * 5,2,8和9,1,3,4,
	     * 9和5比较,1和2比较,3和8比较,4和比其下标值小increment的数组值相比较
	     * 第一次排序后数组为5, 1,3, 9, 2, 8, 4
	     * 第一次后increment的值变为3/2=1,此时对数组进行插入排序
	     * O(n^2). 
	     */
	    public static void shellSort(int[] data) {
	        int j = 0;
	        int temp = 0;
	        //每次将步长缩短为原来的一半
	        for (int increment = data.length / 2; increment > 0; increment /= 2){
		        for (int i = increment; i < data.length; i++) {
		            temp = data[i];
		            for (j = i; j >= increment; j -= increment){
		            	if(temp < data[j - increment]){ //如想从小到大排只需修改这里
		            		data[j] = data[j - increment];
		            	}else{
		            		break;
		            	}
		            } 
		            data[j] = temp;
		        }
	        }
	    }
	    
	    /*
	     * 归并排序:
	     * 将两个(或两个以上)有序表合并成一个新的有序表,
	     * 即把待排序序列分为若干个子序列,每个子序列是有序的。
	     * 然后再把有序子序列合并为整体有序序列。
	     */
	  //归并排序
	    public static void mergeSort(int[] arr){
	        int[] temp =new int[arr.length];
	        internalMergeSort(arr, temp, 0, arr.length-1);
	    }
	    private static void internalMergeSort(int[] a, int[] temp, int left, int right){
	        //当left==right的时,已经不需要再划分了
	        if (left<right){
	            int middle = (left+right)/2;
	            internalMergeSort(a, temp, left, middle);          //左子数组
	            internalMergeSort(a, temp, middle+1, right);       //右子数组
	            mergeSortedArray(a, temp, left, middle, right);    //合并两个子数组
	        }
	    }
	    // 合并两个有序子序列 arr[left, ..., middle] 和 arr[middle+1, ..., right]。temp是辅助数组。
	    private static void mergeSortedArray(int arr[], int temp[], int left, int middle, int right){
	        int i=left;      
	        int j=middle+1;
	        int k=0;
	        while ( i<=middle && j<=right){
	            if (arr[i] <=arr[j]){
	                temp[k++] = arr[i++];
	            }else{
	                temp[k++] = arr[j++];
	            }
	        }
	        while (i <=middle){
	            temp[k++] = arr[i++];
	        }
	        while ( j<=right){
	            temp[k++] = arr[j++];
	        }
	        //把数据复制回原数组
	        for (i=0; i<k; ++i){
	            arr[left+i] = temp[i];
	        }
	    }
	    
	    /*
	     * 堆排序:
	     * 根节点为最大值,大顶堆
	     */
	        //对data数组从0到lastIndex建大顶堆
	        public static void buildMaxHeap(int[] data, int lastIndex){
	             //从lastIndex处节点(最后一个节点)的父节点开始 
	            for(int i=(lastIndex-1)/2;i>=0;i--){
	                //k保存正在判断的节点 
	                int k=i;
	                //如果当前k节点的子节点存在  
	                while(k*2+1<=lastIndex){
	                    //k节点的左子节点的索引 
	                    int biggerIndex=2*k+1;
	                    //如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在
	                    if(biggerIndex<lastIndex){  
	                        //若果右子节点的值较大  
	                        if(data[biggerIndex]<data[biggerIndex+1]){  
	                            //biggerIndex总是记录较大子节点的索引  
	                            biggerIndex++;  
	                        }  
	                    }  
	                    //如果k节点的值小于其较大的子节点的值  
	                    if(data[k]<data[biggerIndex]){  
	                        //交换他们  
	                        swap(data,k,biggerIndex);  
	                        //将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值  
	                        k=biggerIndex;  
	                    }else{  
	                        break;  
	                    }  
	                }
	            }
	        }
	        //交换
	        private static void swap(int[] data, int i, int j) {  
	            int tmp=data[i];  
	            data[i]=data[j];  
	            data[j]=tmp;  
	        } 
	    
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int [] arr = {54,75,13,678,23,74,1,67,75,12};
		/*for(int i=0; i<arr.length;i++){
			System.out.println("请输入第"+i+"个数:");
			arr[i] = sc.nextInt();
		}*/
//		sortBubbling(arr);
//		selectSort(arr);
//		quick(arr);
//		insertSort(arr);
//		shellSort(arr);
//		mergeSort(arr);
		int arrayLength=arr.length;  
        //循环建堆  
        for(int i=0;i<arrayLength-1;i++){  
            //建堆  
            buildMaxHeap(arr,arrayLength-1-i);  
            //交换堆顶和最后一个元素  
            swap(arr,0,arrayLength-1-i);  
            System.out.println(Arrays.toString(arr));  
        }  
        printArr(arr);
	}
	
	public static void printArr(int[] numbers){
		System.out.print("排序后:");
        for(int i = 0 ; i < numbers.length ; i ++ ){
        	System.out.print(numbers[i] + ",");
        }
        System.out.println("");
    }
}

  

原文地址:https://www.cnblogs.com/nn369/p/8006977.html