排序算法-JAVA代码

1、插入排序:

import java.util.Arrays;

public class InsertionSort {
	
	public static void insertionSort(int[] input ,int n)
	{
		int i , j , temp; //temp记录每次插入的值
		//默认已经插入一个值。
		for(i = 1 ; i <= n - 1 ; i++)
		{
			temp = input[i];
			for(j = i ; j > 0 && input[j - 1] > temp ; j--)
			{
				input[j] = input[j - 1]; //每次比较后向后移一位
			}
			input[j] = temp; //将要插入的值插入到属于它的位置
		}
	}
	
	public static void main(String[] args)
	{
		int input[] = {10,15,14,18,20,36,40};
		insertionSort(input, 7);
		System.out.println(Arrays.toString(input));
	}

}

2、希尔排序

import java.util.Arrays;

public class ShellSort {
	
	/**
	 * 希尔排序法(缩小增量法) 属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序的方法。
	 * 基本思想:算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.
	 * 对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行直接插入排序后,排序完成。
	 * @param input
	 * @param n
	 */
	public static void shellSort(int[] input , int n)
	{
		int i , j , temp; //插入法使用的临时变量
		//缩小增量,初始增量为n/2,按照增量的1/2缩小
		for(int incre = n/2 ; incre >= 1 ; incre = incre / 2)
		{
			//从下表incre开始,进行插入操作,初始插入坐标指向第一个插入的位置
			for(i = incre ; i < n ; i++)
			{
				temp = input[i]; //插入元素的值
				for(j = i ; j >= incre &&  input[j - incre] > temp ; j = j - incre)
				{
					input[j] = input[j - incre];
 				}
				input[j] = temp;
			}
		}
	}
	
	public static void main(String[] args)
	{
		int input[] = {10,15,14,18,20,36,40};
		shellSort(input, 7);
		System.out.println(Arrays.toString(input));
	}

}

3、冒泡排序

import java.util.Arrays;

public class BubbleSort {
	
	//冒泡排序,顾名思义,从下往上遍历,每次遍历往上固定一个最小值
	public static void bubbleSort(int[] input , int n)
	{
		for(int i = 0 ; i < n-1 ; i++)
		{
			for(int j = n - 1 ; j >= i + 1 ; j--)
			{
				if(input[j - 1] > input[j])
				{
					int temp = input[j - 1];
					input[j - 1] = input[j];
					input[j] = temp;
				}
			}
		}
	}
	
	//加一个标志位,当某一趟冒泡排序没有元素交换时,则冒泡结束,元素已经有序,可以有效的减少冒泡次数。
	public static void optimizedBubbleSort(int[] input , int n)
	{
		boolean flag = true;
		for(int i = 0 ; i < n-1 && flag ; i++)
		{
			flag = false;
			for(int j = n - 1 ; j >= i + 1 ; j--)
			{
				if(input[j - 1] > input[j])
				{
					int temp = input[j - 1];
					input[j - 1] = input[j];
					input[j] = temp;
					flag = true;
				}
			}
		}
	}
	
	 //   如果0-i已是有序区间,上次的扫描区间是i-n,记上次扫描时最后一次交换的位置lastswappose,
       //	则lastswappose在i-n之间,不难发现i-lastswappose区间已是有序的,
       //	否则这个区间也会发生交换;所以下次扫描区间可以由i-n缩减到lastswappose-n。
		public static void LastSwapPoseBubbleSort(int[] input , int n)
		{
			int lastSwapPose = 0 , lastSwapPoseTemp = 0;
	
			for(int i = 0 ; i < n-1 ; i++)
			{
				lastSwapPose = lastSwapPoseTemp;
				for(int j = n - 1 ; j > lastSwapPose ; j--)
				{
					if(input[j - 1] > input[j])
					{
						int temp = input[j - 1];
						input[j - 1] = input[j];
						input[j] = temp;
						lastSwapPoseTemp = j;
					}
				}
				if(lastSwapPose == lastSwapPoseTemp)
				{
					break;
				}
			}
		}
	public static void main(String[] args)
	{
		int input[] = {10,15,14,18,20,36,40};
//		bubbleSort(input, 7);
		optimizedBubbleSort(input, 7);
		System.out.println(Arrays.toString(input));
	}

}

4、快速排序

import java.util.Arrays;

/**
 * 对于给定的一组记录,选择一个基准元素,通常选择第一个元素或者最后一个元素,
 * 通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,
 * 此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分,直到序列中的所有记录均有序为止。
 * 算法优化:
 * (1)在递归到规模比较小时,使用选择排序/插入排序代替。
 * (2)选取一个比较靠谱的pivot。(取first,取last,取middle,取三者的中)
 * (3)使用循环代替递归。
 * @author 李顶圣
 *
 */
public class Quicksort {

	/*
	 * 排序的核心算法
	 * 
	 * @param input 待排序数组
	 * 
	 * @param startIndex 开始位置
	 * 
	 * @param endIndex 结束位置
	 */
	private static void sortCore(int[] input, int startIndex, int endIndex) {
		if (startIndex >= endIndex) {
			return;
		} else {
			int boundary = getBoundary(input, startIndex, endIndex);
			sortCore(input, startIndex, boundary - 1);
			sortCore(input, boundary + 1, endIndex);
		}
	}

	/*
	 * 交换并返回分界点
	 * 
	 * @param input 待排序数组
	 * 
	 * @param startIndex 开始位置
	 * 
	 * @param endIndex 结束位置
	 * 
	 * @return 分界点
	 */
	private static int getBoundary(int[] input, int startIndex, int endIndex) {
		int standard = input[startIndex]; // 定义标准
		int leftIndex = startIndex; // 左指针
		int rightIndex = endIndex; // 右指针

		while (leftIndex < rightIndex) {
			while (leftIndex < rightIndex && input[rightIndex] >= standard) {
				rightIndex--;
			}
			input[leftIndex] = input[rightIndex];
			while (leftIndex < rightIndex && input[leftIndex] <= standard) {
				leftIndex++;
			}
			input[rightIndex] = input[leftIndex];
		}
		input[leftIndex] = standard;
		return leftIndex;

	}
	
	public static void main(String[] args)
	{
		int input[] = {20,15,14,18,21,36,40,10};
		sortCore(input, 0, 7);
		System.out.println(Arrays.toString(input));
	}

}

5、选择排序

import java.util.Arrays;

public class SelectionSort {
	/**
	 * 选择排序,就是每次选出待排序部分最小值,与其应该放的位置上的元素进行替换,比较的次数多,但是替换的次数会降低。
	 * @param input
	 * @param n
	 */
	private static void selectionSort(int[] input , int n)
	{
		int min = 0;
		for(int i = 0 ; i < n - 1 ; i++)
		{
			min = i ;
			for(int j = i + 1 ; j <= n - 1 ; j++)
			{
				if(input[min] > input[j])
				{
					min = j;
				}
			}
			int temp = input[i];
			input[i] = input[min];
			input[min] = temp;
		}
	}
	
	public static void main(String[] args)
	{
		int input[] = {10,15,14,18,20,36,40};
//		bubbleSort(input, 7);
		selectionSort(input, 7);
		System.out.println(Arrays.toString(input));
	}

}

6、堆排序

public class HeapSort {
	// 构建大根堆:将array看成完全二叉树的顺序存储结构
	private int[] buildMaxHeap(int[] array) {
		// 从最后一个节点array.length-1的父节点(array.length-1-1)/2开始,直到根节点0,反复调整堆
		for (int i = (array.length - 2) / 2; i >= 0; i--) {
			adjustDownToUp(array, i, array.length);
		}
		return array;
	}

	// 将元素array[k]自下往上逐步调整树形结构  
	private void adjustDownToUp(int[] array, int k, int length) {
		int temp = array[k];
		for (int i = 2 * k + 1; i <= length - 1; i = 2 * i + 1) { // i为初始化为节点k的左孩子,沿节点较大的子节点向下调整
			if (i < length - 1 && array[i] < array[i + 1]) { // 取节点较大的子节点的下标
				i++; // 如果节点的右孩子>左孩子,则取右孩子节点的下标
			}
			if (temp >= array[i]) { // 根节点>=左右子女中关键字较大者,调整结束
				break;
			} else { // 根节点<左右子女中关键字较大者
				array[k] = array[i]; // 将左右子结点中较大者array[i]调整到双亲节点上
				k = i; // 【关键】修改k值,以便继续向下调整
			}
		}
		array[k] = temp; // 被调整的结点的值放人最终位置
	}

	// 堆排序
	public int[] heapSort(int[] array) {
		array = buildMaxHeap(array);  // 初始建堆,array[0]为第一趟值最大的元素
		for (int i = array.length - 1; i >= 1; i--) {
			int temp = array[0]; // 将堆顶元素和堆低元素交换,即得到当前最大元素正确的排序位置
			array[0] = array[i];
			array[i] = temp;
			adjustDownToUp(array, 0, i); // 整理,将剩余的元素整理成堆,注意i的含意
		}
		return array;
	}

	public void toString(int[] array) {
		for (int i : array) {
			System.out.print(i + " ");
		}
	}

	public static void main(String args[]) {
		HeapSort hs = new HeapSort();
		int[] array = {4,5,1,6,2,7,3,8};
		System.out.print("构建大根堆:");
		hs.toString(hs.buildMaxHeap(array));
		System.out.print("\n" + "大根堆排序:");
		hs.toString(hs.heapSort(array));
	}
}

7、归并排序

import java.util.Arrays;

public class MergeSort {

	/**
	 * 归并排序,递归做法,分而治之
	 * 先使每个子序列有序,再将两个已经排序的序列合并成一个序列的操作。若将两个有序表合并成一个有序表,称为二路归并。
	 * @param input
	 * @param left
	 */
	public static void mergeSort(int[] input , int left , int right)
	{
		int mid = (right + left) / 2;
		if(left < right)
		{
			//左边
			mergeSort(input, left, mid);
			//右边
			mergeSort(input, mid + 1, right);
			//左右归并
			merge(input, left, mid, right);
		}
	}
	
	//将左右俩组的按序子序列排列成按序序列
	public static void merge(int[] input , int left , int mid , int right)
	{
		int[] temp = new int[right - left + 1];//对两个有序序列合并后存储的临时数组
		int i = left; //左指针
		int j = mid + 1; //右指针
		int k = 0;
		// 把较小的数先移到新数组中
		while(i <= mid && j <= right)
		{
			if(input[i] < input[j])
			{
				temp[k++] = input[i++];
			}else {
				temp[k++] = input[j++];
			}
		}
		// 把左边剩余的数移入数组
		while(i <= mid)
		{
			temp[k++] = input[i++];
		}
		// 把右边边剩余的数移入数组
		while(j <= right)
		{
			temp[k++] = input[j++];
		}
		 // 把新数组中的数覆盖原数组
		for(int m = 0 ; m < temp.length ; m++)
		{
			input[m + left] = temp[m];
		}
	}
	
	public static void main(String[] args)
	{
		int input[] = { 51, 46, 20, 18, 65, 97, 82, 30, 77, 50 };
        mergeSort(input, 0, input.length - 1);
        System.out.println("排序结果:" + Arrays.toString(input));
	}
}

8、桶排序

import java.util.ArrayList;
import java.util.Collections;


/**
 * 适用范围:
 * 桶排序可用于最大最小值相差较大的数据情况,比如[9012,19702,39867,68957,83556,102456]。
 * 但桶排序要求数据的分布必须均匀,否则可能导致数据都集中到一个桶中。比如[104,150,123,132,20000], 这种数据会导致前4个数都集中到同一个桶中。导致桶排序失效。
 * 过程:
 * 桶排序的基本思想是:把数组 arr 划分为n个大小相同子区间(桶),每个子区间各自排序,最后合并。
 * 计数排序是桶排序的一种特殊情况,可以把计数排序当成每个桶里只有一个元素的情况。
 * 1.找出待排序数组中的最大值max、最小值min
 * 2.我们使用 动态数组ArrayList 作为桶,桶里放的元素也用 ArrayList 存储。桶的数量为(max-min)/arr.length+1
 * 3.遍历数组 arr,计算每个元素 arr[i] 放的桶
 * 4.每个桶各自排序
 * 5.遍历桶数组,把排序好的元素放进输出数组
 * @author 李顶圣
 *
 */
public class 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());
	    
	}

}

9、全排序(不属于十大排序算法,在这做个笔记)

//全排列问题,首先列出所有情况,在进行排序;
public class FullSort {

	public static void main(String[] args) {
		fullSortList();
	}
	
	
	public static void fullSortList(){
		String A[] = new String[]{"a","b","c","d"};
		List<String> list = new ArrayList<>();
		Queue<String> queue = new LinkedList<>();
		queue.offer("a");
		queue.offer("b");
		queue.offer("c");
		queue.offer("d");
		//列出所有情况,按照长度1,2,3...一直列举;
		for(int i = 0 ; i < 4 ; i++)
		{
			int n = queue.size();
			while(n >= 1 && queue.peek() != null)
			{
				String temp = queue.poll();
				for(int j = 0 ; j < 4 ; j++)
				{
					String temp1 = A[j];
					if(!temp.contains(temp1))
					{
						queue.offer(temp + temp1);
					}
				}
				list.add(temp);
			}
					
		}
		Collections.sort(list);
		for(int i = 0 ; i < list.size() ; i++)
		{
			System.out.println(list.get(i));
		}
	}


}

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值