Java实现常见的排序算法

常见的排序算法

本文采取的排序均按照从小到大排

插入排序

主要由两个部分组成,(1)将大数后移(2)将空出的位置进行赋值

private static int[] sort(int[] array) {
		for (int i = 1; i < array.length; i++) {
			int temp = array[i];
			int j = i - 1;
			while(j>=0&&array[j]>temp) {
				array[j+1] = array[j];//向左遍历,寻找比自己大的,并将大的数后移
				j--;
			}
			
			array[j+1] = temp;//将后移后多出来的位置留给自己,若未发生移动则在自己的位置上赋自己的值
		}
		return array;
	}

希尔排序

插入排序改改就行,相当于多了一个步长

	private static int[] sort(int[] array) {
		int [] keys = new int [] {5,3,1};	
		for (int m = 0; m < keys.length; m++) {
			int key = keys[m];
			for (int i = 1 * keys[m]; i < array.length; i+=key) {
				int temp = array[i];
				int j = i - key;
				while(j>=0&&array[j]>temp) {
					array[j+key] = array[j];//向左遍历,寻找比自己大的,并将大的数后移
					j-=key;
				}
				
				array[j+key] = temp;//将后移后多出来的位置留给自己,若未发生移动则在自己的位置上赋自己的值
			}
		}
		return array;
	}

冒泡排序

将左右两个数进行比较,如果左边大于右边,则进行交换,一轮做完后,会将次轮中最大的数移动到最右边,下次遍历时就可以不必遍历到最后

	private static int[] sort(int[] array) {
		for (int i = 0; i < array.length; i++) {
			for (int j = 1; j < array.length-i; j++) {//右边已经排好序,可以不遍历到array.length
				if(array[j]<array[j-1]) {//左边大于右边,则进行交换
					int temp = array[j];
					array[j] = array[j-1];
					array[j-1] = temp;
				}
			}
		}
		return array;
	}

选择排序

最简单的排序,选出最小的数的下标然后交换即可

	private static int[] sort(int[] array) {
		int pos = 0;
		for (int i = 0; i < array.length; i++) {
			for (int j = i; j < array.length; j++) {
				if(array[pos] > array[j]) {
					pos = j;
				}
			}
			int temp = array[pos];
			array[pos] = array[i];
			array[i] = temp;
			pos = i+1;
		}
		return array;
	}

快速排序

选择基准值,其左边的数均比基准值小,右边的数都比基准值大,然后递归缩小范围

private static void sort(int[] array,int low ,int high) {
		int l = low;
		int h = high;
		int key = array[l];
		
		while(l<h) {
            //先从右边开始,选出比基准值小的数然后与左边进行交换
			while(l<h&&key<=array[h]) {
				h--;
			}
			if(l<h) {//采用交换法
				int temp = array[l];
				array[l] = array[h];
				array[h] = temp;
			}
            //再从左边开始,选出比基准值大的数然后与右边进行交换
			while(l<h&&key>=array[l]) {
				l++;
			}
			if(l<h) {
				int temp = array[l];
				array[l] = array[h];
				array[h] = temp;
			} 
		}
		//递归调用,进行分割
		if(low<l-1) {
			sort(array,low,l-1);
		}
		if(high>l+1) {
			sort(array,l+1,high);
		}
	}

归并排序

将数组进行划分,然后一边根据大小合并,一边排序

/**
	 * 分解+合并
	 * 
	 * @param arr   需要排序的数组
	 * @param left  起点
	 * @param right 终点
	 */
	private static void mergeSort(int[] arr, int left, int right) {
		if (left < right) {
			int mid = (left + right) / 2;
			mergeSort(arr, left, mid );
			mergeSort(arr, mid+1, right);
			merge(arr, left, mid, right);
		}
	}

	/**
	 * 合并
	 * 
	 * @param arr   原数组
	 * @param left  左段起点
	 * @param mid   两段的分割点
	 * @param right 右端的终点
	 */
	private static int[] merge(int[] arr, int left, int mid, int right) {
		int[] temp = new int[arr.length+1];
		int pos = mid+1;
		int tPos = 0;
		int tl = left;
		// 遍历arr的左右两段存入temp
		while (left <= mid && pos <= right) {
			if (arr[left] < arr[pos]) {
				temp[tPos++] = arr[left++];
			} else {
				temp[tPos++] = arr[pos++];
			}
		}
		// 右段已经结束,遍历左段
		if (pos >= right) {
			while (left <= mid) {
				temp[tPos++] = arr[left++];
			}
		}
		// 左段已经结束,遍历右段
		if (left >= mid) {
			while (pos <= right) {
				temp[tPos++] = arr[pos++];}}
        //将temp赋到原数组
		int t = 0;
		int tempLeft = tl;
		while (tempLeft <= right) {
			arr[tempLeft++] = temp[t++];
		}
		return temp;
	}

基数排序

基数排序通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用

	private static void radixSort(int[] arr) {
		int maxLength = getMaxLength(arr);
		int[][] bucket = new int[10][10];
		int[] bucketCounts = new int[10];
		//依据所有数字中最长位的大小进行循环
		for (int m = 0,basic = 1; m < maxLength; m++,basic *= 10) {
			//根据某一位大小,将数字先挂到bucket中
			for (int i = 0; i < arr.length; i++ ) {
				int key = arr[i] / basic % 10;
				bucket[key][bucketCounts[key]] = arr[i];
				bucketCounts[key]++;
			}
			//将bucket中的数字依次取出,完成一轮排序
			int pos = 0;
			for (int index = 0; index < bucketCounts.length; index++) {
				if (bucketCounts[index] != 0) {
					for (int i=0;i<bucketCounts[index];i++) {
						arr[pos++] = bucket[index][i];
					}
				}
			}
			//初始化bucketCounts为0,方便进行下一步bucket挂载和取出
			for (int i = 0; i < bucketCounts.length; i++) {
				bucketCounts[i] = 0;
			}
		}
	}

二叉树排序

将数字取出放入一颗"树"中,该“树”左小右大

public class MyTest {

	public static void main(String[] args) {
		int []nums = new int[] {45,65,-8,75,5,61,1};
		Node root = new Node(nums[0]);
		for (int i = 1; i < nums.length; i++) {
			root.add(new Node(nums[i]));
		}
		root.printNodes();
	}
}

class Node{
	Node left;
	Node right;
	int value;
	public Node(int value) {
		super();
		this.value = value;
	}
	
    //添加一个节点
	public void add(Node temNode) {
		if(this.value>temNode.value) {//左小右边大于等于
			if(this.left==null) {
				this.left = temNode;
				
			}else {
				this.left.add(temNode);//让左边的节点去添加新的节点
			}
		}else {
			if(this.right==null) {
				this.right = temNode;
				
			}else {
				this.right.add(temNode);//让右边的节点去添加新的节点
				
			}
		}
	}
	
    //中序遍历
	public void printNodes() {
		if(this.left != null) {
			this.left.printNodes();
		}
		System.out.print(this.value+"\t");
		if(this.right != null) {
			this.right.printNodes();
		}
		
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值