排序算法

6 篇文章 0 订阅

排序演示链接:http://www.atool9.com/sort.php
冒泡排序,直接插入排序,快速排序,希尔排序,选择排序,归并排序,基数排序,用队列实现基数排序

冒泡排序

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端。
代码实现:

package com.test;

import java.util.Arrays;

public class test {
	public static void main(String[] args) {
		int[] arr = {1,4,6,8,3,10,2,6,8,9};
		bubbleSort(arr);
		System.out.println(Arrays.toString(arr));
	}

	public static void bubbleSort(int[] arr){
		for (int i = 0;i<arr.length-1;i++){
			for (int j = 0;j<arr.length-i-1;j++){
				if (arr[j]>arr[j+1]){
					int temp = arr[j+1];
					arr[j+1] = arr[j];
					arr[j] = temp;
				}
			}
		}
	}
}

直接插入排序

插入排序基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。插入排序的基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
代码实现:

public static void main(String[] args) {
		//插入排序
		int[] arr = new int[]{5,8,1,3,6,4,9};
		insertSort(arr);
		System.out.println(Arrays.toString(arr));
	}

	public static void insertSort(int[] arr){
		//遍历所有的数字
		for(int i=1;i<arr.length;i++){
			//如果当前数字比前一个数字小
			if (arr[i]<arr[i-1]){
				int temp = arr[i];
				int j;
				//遍历当前数字前面所有的数字
				for (j=i-1;j>=0&&temp<arr[j];j--){
					//把前一个数字赋给后一个数字
					arr[j+1] = arr[j];
				}
				//把临时变量(外层for循环的当前元素)赋给不满足条件的后一个元素
				arr[j+1] = temp;
			}
		}
	}

快速排序

快速排序(Quicksort)是对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
代码实现:

public static void main(String[] args) {
		//快速排序
		int[] arr = new int[]{5,8,1,3,6,4,9};
		quickSort(arr,0,arr.length-1);
		System.out.println(Arrays.toString(arr));
	}

	public static void quickSort(int[] arr,int start,int end){
		if (start < end){
			//把数组中的第0个数字作为标准
			int startNum = arr[start];
			//记录需要排序的下标
			int low = start;
			int high = end;
			//循环找比标准数大的数和比标准数小的数
			while (low<high){
				//如果右边的数字比标准数大,则向前移
				while (low<high && startNum<=arr[high]){
					high--;
				}
				//使用右边的数字替代左边的数字
				arr[low] = arr[high];
				//如果左边的数字比标准数小
				while (low<high && arr[low]<=startNum){
					low++;
				}
				//使用左边的数字替代高的部分
				arr[high] = arr[low];
			}
			//把标准数赋给低的所在位置
			arr[low] =startNum;
			//处理所有小的数字
			quickSort(arr,start,low);
			//处理大的数字
			quickSort(arr,low+1,end);
		}
	}
	public static void sort(int[] arr,int start,int end){
		if(start<end){
			int startNum = arr[start];
			int low = start;
			int high = end;

			while(low<high){
				while(startNum<=arr[high] && low<high){
					high--;
				}

				while(startNum>=arr[low] && low<high){
					low++;
				}
				if(low<high){
					int temp = arr[low];
					arr[low]=arr[high];
					arr[high]=temp;
				}

			}
			arr[start] = arr[low];
			arr[low] = startNum;
			sort(arr,start,low);
			sort(arr,low+1,end);
		}
	}

希尔排序

希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
代码实现:

public static void main(String[] args) {
		//希尔排序
		int[] arr = new int[]{5,8,1,3,6,4,9};
		ShellSort(arr);
		System.out.println(Arrays.toString(arr));
	}

	public static void ShellSort(int[] arr){
		int k = 1;
		//遍历所有的步长
		for (int d = arr.length/2;d>0;d/=2){
			//遍历所有的元素
			for (int i = d;i<arr.length;i++){
				//遍历本组中所有的元素
				for(int j=i-d;j>=0;j-=d){
					//如果当前元素大于加上步长后的那个元素
					if (arr[j]>arr[j+d]){
						int temp = arr[j];
						arr[j] = arr[j+d];
						arr[j+d] = temp;
					}
				}
			}
			System.out.println("第"+k+"次遍历结果为:"+Arrays.toString(arr));
			k++;
		}
	}

选择排序

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
代码实现:

public static void main(String[] args) {
		//选择排序
		int[] arr = new int[]{5,8,1,3,6,4,9};
		selectSort(arr);
		System.out.println(Arrays.toString(arr));
	}

	public static void selectSort(int[] arr){
		//遍历所有的数
		for (int i=0;i<arr.length;i++){
			int minIndex = i;
			//把当前遍历的数和后面所有的数进行比较,并记录最小的数的下标
			for (int j=i+1;j<arr.length;j++){
				//如果后面的数更小
				if (arr[minIndex]>arr[j]){
					//记录最小的数的下标
					minIndex = j;
				}
			}
			//如果最小的数和当前遍历数的下标不一致,说明下标为minIndex的数比当前遍历的数更小
			if (i != minIndex){
				int temp = arr[i];
				arr[i] = arr[minIndex];
				arr[minIndex] = temp;
			}
		}
	}

归并排序

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
代码实现:

public static void main(String[] args) {
		int[] arr = new int[]{3,5,7,9,1,4,0,3,8};
		mergeSort(arr,0,arr.length-1);
		System.out.println(Arrays.toString(arr));
	}

	public static void mergeSort(int[] arr,int low,int high){
		int middle=(high+low)/2;
		if (low<high){
			mergeSort(arr,low,middle);
			mergeSort(arr,middle+1,high);
			merge(arr,low,middle,high);
		}
	}

	public static void merge(int[] arr,int low,int middle,int high){
		//用于存储归并后的临时数组
		int[] temp = new int[high-low+1];
		//用于记录第一个数组中需要遍历的下标
		int i = low;
		//用于记录第二个数组中需要遍历的下标
		int j = middle+1;
		//用于记录在临时数组中存放的下标
		int index = 0;
		//循环遍历两个数组,取出小的数字放入temp中
		while (i<=middle&&j<=high){
			if (arr[i]<=arr[j]){
				//第一个数组的数据更小,把小的数据放入临时数组中,让下标右移一位
				temp[index] = arr[i];
				i++;
			}else{
				temp[index] = arr[j];
				j++;
			}
			index++;
		}
		//处理多余的数据
		while (j<=high){
			temp[index] = arr[j];
			j++;
			index++;
		}
		while (i<=middle){
			temp[index] = arr[i];
			i++;
			index++;
		}
		//把临时数组中的数据重新存入原数组
		for (int k = 0;k<temp.length;k++){
			arr[k+low] = temp[k];
		}
	}

基数排序

适合位数不一致的数组排序,排的次数等于最大数的位数
代码实现:

public static void main(String[] args) {
		int[] arr = new int[]{345,52,7,9907,12,4,120,13,238};
		radixSort(arr);
		System.out.println(Arrays.toString(arr));
	}

	public static void radixSort(int[] arr){
		//存数组中最大的数,决定排序次数
		int max =Integer.MIN_VALUE;
		for (int  i = 0;i<arr.length;i++){
			if (arr[i]>max){
				max=arr[i];
			}
		}
		//求最大数组的位数,即排序次数
		int count = (max+"").length();
		//用于临时存储数据的数组
		int[][] temp = new int[10][arr.length];
		//用于记录在相应的数组中存放的数字的数量
		int[] counts = new int[10];
		for (int i = 0,n=1;i<count;i++,n*=10){
			for (int j = 0;j<arr.length;j++){
				//计算余数
				int ys = arr[j] / n % 10;
				//把当前遍历的数字放到指定的数组中
				temp[ys][counts[ys]] = arr[j];
				//记录数量
				counts[ys]++;
			}
			//记录取的元素的下标
			int index = 0;
			//取出数字
			for (int k = 0;k<counts.length;k++){
				//记录数量不为0的话取值
				if (counts[k] != 0){
					for (int m = 0;m<counts[k];m++){
						//取出元素
						arr[index] = temp[k][m];
						index++;
					}
					//置空数量
					counts[k] = 0;
				}
			}
		}

	}

用队列实现基数排序

队列代码实现:

package com.test;

public class MyQueue {

    int[] elements;

    public MyQueue(){
        elements = new int[0];
    }

    //入队
    public void add(int element){
        //创建一个数组
        int[] newArr = new int[elements.length+1];
        //把原数组中的元素复制到新数组中
        for (int i = 0;i<elements.length;i++){
            newArr[i] = elements[i];
        }
        //把添加的元素放入新数组中
        newArr[elements.length] = element;
        elements = newArr;
    }

    //出队
    public int pull(){
        //把数组中的第0个元素取出
        int element = elements[0];
        //取出一个新的数组
        int[] newArr = new int[elements.length-1];
        //复制原数组中的元素到新数组中
        for (int i = 0;i<newArr.length;i++){
            newArr[i] = elements[i+1];
        }
        //替换数组
        elements=newArr;
        return element;
    }

    //判断队列是否为空
    public boolean isEmpty() {
        return elements.length==0;
    }
}

用队列实现的基数排序代码实现:

public static void main(String[] args) {
		int[] arr = new int[]{345,52,7,9907,12,4,120,13,238};
		radixSort(arr);
		System.out.println(Arrays.toString(arr));
	}

	public static void radixSort(int[] arr){
		//存数组中最大的数,决定排序次数
		int max =Integer.MIN_VALUE;
		for (int  i = 0;i<arr.length;i++){
			if (arr[i]>max){
				max=arr[i];
			}
		}
		//求最大数组的位数,即排序次数
		int count = (max+"").length();
		//用于临时存储数据的队列
		MyQueue[] temp = new MyQueue[10];
		//为队列数组赋值
		for (int t = 0;t<temp.length;t++){
			temp[t] = new MyQueue();
		}
		for (int i = 0,n=1;i<count;i++,n*=10){
			for (int j = 0;j<arr.length;j++){
				//计算余数
				int ys = arr[j] / n % 10;
				//把当前遍历的数字放到指定的队列中
				temp[ys].add(arr[j]);
			}
			//记录取的元素的下标
			int index = 0;
			//取出所有队列中的数字
			for (int k = 0;k<temp.length;k++){
				//当前遍历的队列不为空,取值
				while (!temp[k].isEmpty()){
					//取出元素
					arr[index] = temp[k].pull();
					index++;
				}
			}
		}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值