十大经典排序

十大经典排序

一、10种经典的排序方法

1、选择排序

for(int i = 0; i < length - 1; i++) {
    for(int j = i + 1; j < length; j++) {
	    if(Array[i] > Array[j]) {
		    int num = Array[i];
			Array[i] = Array[j];
			Array[j] = num;
		}
	}
}   

2、插入排序

for(int i = 1; 	i < length; i++) {
    int temp = Array[i];
	int k = i - 1;
	while(k >= 0 && Array[k] > temp) {
	    Array[k + 1] = Array[k];
	    k--;
	}
	Array[k + 1] = temp;
}

3、冒泡排序

for(int i = 0; i< length; i ++) {
    for(int j = 0; j < length - i -1; j++) {
	    if(Array[j + 1] < Array[j]) {
		    temp = Array[j];
			Array[j] = Array[j + 1];
			Array[j + 1] = temp;
		}
	}
}

4、希尔排序(Shell Sort)

int len = array.length;
int temp, gap = len / 2;
while (gap > 0) {
    for (int i = gap; i < len; i++) {
        temp = array[i];
        int preIndex = i - gap;
        while (preIndex >= 0 && array[preIndex] > temp) {
            array[preIndex + gap] = array[preIndex];
            preIndex -= gap;
        }
        array[preIndex + gap] = temp;
    }
    gap /= 2;
}

5、归并排序

public static void MergeSort(int[] array) {
	sort(array, 0, array.length - 1);
}

public static void sort(int[] array, int start, int end) {
	if(start == end) {
		return;
	}
	int mid = start + ((end - start) >> 1);
	sort(array, start, mid);
	sort(array, mid + 1, end);
	merge(array, start, mid, end);
}

public static void merge(int[] array, int start, int mid, int end) {
	int[] temp = new int[end - start + 1];
	int p1 = start, p2 = mid + 1, i = 0;
	while(p1 <= mid && p2 <= end) {
		temp[i++] = array[p1] > array[p2] ? array[p2++] : array[p1++];
	}
	while(p1 <= mid) {
		temp[i++] = array[p1++];
	}
	while(p2 <= end) {
		temp[i++] = array[p2++];
	}
	for(i = 0; i < temp.length; i++) {
		array[start + i] = temp[i];
	}
}

6、快排序

public static void quickSort(int[] array) {
	if(array == null || array.length <= 1) {
		return;
	}
	quickSort(array, 0, array.length - 1);
}

public static void quickSort(int[] array, int start, int end) {
	if(start >= end) {
		return;
	}
	int p1 = start, p2 = end, index = array[p1];
	while(p1 < p2) {
		while(p1 < p2 && array[p2] >= index) { // 向左寻找第一个小于index的数
			p2--;
		}
        if(p1 < p2) {
        	array[p1++] = array[p2];
        }
        while(p1 < p2 && array[p1] <= index) {// 向右寻找第一个大于index的数
        	p1++;
        }
        if(p1 < p2) {
        	array[p2--] = array[p1];
        }
	}
	array[p1] = index;                 // 将基准数填入最后的坑
	quickSort(array, start, p1 - 1);   //递归分治左半部分
	quickSort(array, p1 + 1, end);      //递归分治右半部分
}

7、堆排序

public static void heapSort(int[] array) {
    int length = array.length - 1;
	int beginIndex = (length - 1) >> 1;
	/*
         *  第一步:将数组堆化
         *  beginIndex = 第一个非叶子节点。
         *  从第一个非叶子节点开始即可。无需从最后一个叶子节点开始。
         *  叶子节点可以看作已符合堆要求的节点,根节点就是它自己且自己以下值为最大。
         */
	for(int i = beginIndex; i >= 0; i--) {
	    maxHeapify(i, length);
	}
	/*
    * 第二步:对堆化数据排序
    * 每次都是移出最顶层的根节点A[0],与最尾部节点位置调换,同时遍历长度 - 1。
    * 然后从新整理被换到根节点的末尾元素,使其符合堆的特性。
    * 直至未排序的堆长度为 0。
    */
	for(int j = length; j >= 0; j--) {
	    swap(0,j);
		maxHeapify(0, j - 1);
	}
	private void swap(int i,int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
	
	/**
    * 调整索引为 index 处的数据,使其符合堆的特性。
    * @param index 需要堆化处理的数据的索引
    * @param len 未排序的堆(数组)的长度
    */
	public void maxHeapify(int index, int length) {
	    int left = (index << 1) + 1;        //左节点
		int right = left + 1;               //右节点
		int Max = left;
		if(left > length) {
		    return ;
		}
		if(right <= length && array[left] < array[right]) {
		    Max = right;
		}
		if(array[index] < array[Max]) {
		    swap(Max, Index);
			maxHeapify(Max, length);
		}
	}
}

8、计数排序

public static int[] countSort1(int[] arr){
    if (arr == null || arr.length == 0) {
        return null;
    }
    
    int max = Integer.MIN_VALUE;
    int min = Integer.MAX_VALUE;
    
    //找出数组中的最大最小值
    for(int i = 0; i < arr.length; i++){
        max = Math.max(max, arr[i]);
        min = Math.min(min, arr[i]);
    }
    
    int help[] = new int[max];
    
    //找出每个数字出现的次数
    for(int i = 0; i < arr.length; i++){
        int mapPos = arr[i] - min;
        help[mapPos]++;
    }
    
    int index = 0;
    for(int i = 0; i < help.length; i++){
        while(help[i]-- > 0){
            arr[index++] = i+min;
        }
    }
    
    return arr;
}
public int[] countSort(int[] array) {
    int res = new int[array.length];
	int max = array[0], min = array[0];
	//取得最大和最小值
	for(int a : array) {
	    if(a > max){
		    max = a;
		}
		if(a < min){
		    min = a;
		}
	}
	int[] arrayTest = new int[max - min + 1];
	for(int ia : array) {
	    arrayTest[ia - min] += 1; 
	}
	for (int i = 1; i < arrayTest.length; i++){
	    arrayTest[i] += arrayTest[i - 1];
	}
	
	for(int i = arrayTest.length - 1; i >= 0; i++){
	    int where = array[i] - min;
		int sumAccount = arrayTest[where]--;
		res[sumAccount - 1] = array[i];
	}
	return res;
}

https://www.jianshu.com/p/86c2375246d7
https://blog.csdn.net/OneDeveloper/article/details/88406776

9、桶排序(BucketSort是计数排序的升级版本)

public static void bucketSort(int[] arr){
    int max = Integer.MIN_VALUE;
    int min = Integer.MAX_VALUE;
    for(int i = 0; i < arr.length; i++){
        max = Math.max(max, arr[i]);
        min = Math.min(min, arr[i]);
    }
    //桶数
    int bucketNum = (max - min) / arr.length + 1;
    ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
    for(int i = 0; i < bucketNum; i++){
        bucketArr.add(new ArrayList<Integer>());
    }
    
    //将每个元素放入桶
    for(int i = 0; i < arr.length; i++){
        int num = (arr[i] - min) / (arr.length);
        bucketArr.get(num).add(arr[i]);
    }
    
    //对每个桶进行排序
    for(int i = 0; i < bucketArr.size(); i++){
        Collections.sort(bucketArr.get(i));
    }
    System.out.println(bucketArr.toString());
    
}

https://www.cnblogs.com/zer0Black/p/6169858.html#3

10、基数排序

请等待梳理
https://blog.csdn.net/zhen921/article/details/80354096

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值