手写常用排序算法(插入,希尔,快排,选择,堆排序),java实现

在排序算法的复习当中,有些算法还是比较难理解的,好在以前打下的基础,再次学习轻松很多,下面记录下手写常用的排序算法。

直接插入排序的性能分析


1. 最好情况:O(n) 
2. 平均情况:O(n^2) 
3. 最坏情况:O(n^2) 
空间复杂度:O(1) 
稳定性:稳定(相同元素的相对位置不会改变)

希尔排序(第一个突破O(n^2)的排序算法)的性能分析:

会根据增量的不同而不同,一般来说: 

1. 最好情况:O(n^1.3) 
2. 最坏情况:O(n^2) 
空间复杂度:O(1) 
稳定性:不稳定(相同元素的相对位置会改变)

快速排序的性能分析:

 
1. 最好情况:O(nlog2(n)) 
2. 平均情况:O(nlog2(n)) 
3. 最坏情况:O(n^2) 
空间复杂度:O(log2(n)) 
稳定性:不稳定(相同元素的相对位置会改变)

简单选择排序的性能分析:

 
1. 最好情况:O(n^2) 
2. 平均情况:O(n^2) 
3. 最坏情况:O(n^2) 
空间复杂度:O(1) 
稳定性:不稳定(相同元素的相对位置会改变)

堆排序的性能分析:

 
1. 最好情况:O(nlog2(n)) 
2. 平均情况:O(nlog2(n)) 
3. 最坏情况:O(nlog2(n)) 
空间复杂度:O(1) 
稳定性:不稳定(相同元素的相对位置会改变)

package com.me.sorts;

import java.net.InetAddress;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter.DEFAULT;

public  class Sorts {
	
	/**
	 * 插入排序
	 * @param a 
	 */
	public static void InsertSort(int[] a) {
		if (a==null || a.length<=0) { //排空
			System.out.println("数组为空");
			return ;
		}

		int temp=0; //暂存要插入的元素
		int j=0;
		for (int i = 1,len=a.length; i <len; i++) {  //遍历数组
			temp=a[i];
			j=i-1;   
			for (; j>=0 && a[j]>temp;j--) {  //如果a[i]之前的数比要插入的temp大,该数后移。注意j>=0
				a[j+1]=a[j];
			}
			a[j+1]=temp; //当循环结束,也就是temp比a[j]大或者相等,或者最小时(j=-1),插入到a[j]后面
		}
	}

	/**
	 * 希尔排序
	 * @param a
	 */
	public static void shellSort(int[] a) {
		if (a==null || a.length<=0) { //排空
			System.out.println("数组为空");
			return ;
		}
		int temp=0; //暂存要插入的元素
		int len=a.length;
		int j=0;
		for (int d = len/2; d>0; d/=2) { //取d/2来分割排序记录
			for (int i = d; i<len; i++) {//从d开始,循环到结束
				temp=a[i];
				j=i-d;  //取第前d个元素作为比较
				for (; j>=0 && a[j]>temp; j-=d) { //连续以d为分割比较
					a[j+d]=a[j];
				}
				a[j+d]=temp; //插入
			}
		}
	}

	/**
	 * 冒泡排序改进版
	 * @param a
	 */
	public static void bubbleSort(int[] a) {
		int exchange=a.length-1;
		int bound=0;
		while (exchange!=0) {
			bound=exchange;
			exchange=0;
			for (int i = 0; i < bound; i++) {
				if (a[i]>a[i+1]) {
					a[i]=a[i]+a[i+1];
					a[i+1]=a[i]-a[i+1];
					a[i]=a[i]-a[i+1];
					exchange=i;
				}
			}
		}
	}

	/**
	 * 快速排序算法
	 * @param a
	 * @param first
	 * @param end
	 */
	public static void quickSort(int[] a,int first,int end) {
		if (first<end) {
			int pivot=partition(a, first, end); //开始对区间进行排序,返回最终的轴值
			quickSort(a, first, pivot-1);       //递归排序左区间,轴值不需要参与排序
			quickSort(a, pivot+1, end);         //递归排序右区间
		}
	}
	/**
	 * 快速排序一次划分算法
	 * @param a
	 * @param first
	 * @param end
	 * @return
	 */
	public static int partition(int a[],int first,int end) {
		int i=first,j=end;
		while (i<j) {
			while (i<j && a[j]>=a[i]) { //从右侧开始扫描,直到找到右侧的比左侧小的数,然后交换位置
				j--;
			}
			if (i<j) {  //交换位置
				a[i]=a[i]+a[j];
				a[j]=a[i]-a[j];
				a[i]=a[i]-a[j];
				i++;
			}

			while (i<j && a[j]>=a[i]) { //从左侧开始扫描,直到找到右侧的比左侧小的数,然后交换位置
				i++;
			}
			if (i<j) { //交换位置
				a[i]=a[i]+a[j];
				a[j]=a[i]-a[j];
				a[i]=a[i]-a[j];
				j--;
			}
		}
		return i;  //轴值记录的最终位置
	}

	/**
	 * 选择排序
	 * @param a
	 */
	public static void selectSort(int[] a) {
		int index=0;
		for (int i = 0,len=a.length; i < len-1; i++) {
			index=i; //存储要交换的位置
			for (int j = i+1; j < len; j++) { //每次循环寻找最小的
				if (a[j]<a[index]) {
					index=j;
				}
			}
			if (index!=i) { //需要交换
				a[i]=a[i]+a[index];
				a[index]=a[i]-a[index];
				a[i]=a[i]-a[index];	
			}
		}
	}
	
	/**
	 * 堆排序
	 * @param a
	 */
	public static void heapSort(int[] a ) {
		int len=a.length;
		for (int i = len/2-1; i >=0; i--) { //初始化建堆
			sift(a,i,len);
		}
		
		 //调整堆结构+交换堆顶元素与末尾元素
        for(int i=len-1;i>0;i--){
        	a[0]=a[i]+a[0];
			a[i]=a[0]-a[i];
			a[0]=a[0]-a[i];
            sift(a,0,i);//重新对堆进行调整
        }
		
	}
	
    /**
     * 堆排序,调整堆方法
     * @param a
     * @param i
     */
	public static void sift(int[] a, int k,int m) {
		int i=k;
		int j=2*i+1;
		while (j<m) {
			if (j+1<m && a[j]<a[j+1]) { //比较j的左右孩子,指向最大的
				j++;
			}
			if (a[i]>a[j]) { //根节点已经大于左右孩子的较大者,排序结束
				break;
			}else {
				//将根节点与结点j交换
				a[i]=a[i]+a[j];
				a[j]=a[i]-a[j];
				a[i]=a[i]-a[j];
				i=j; j=2*i+1; 
			}
			
		}
	}

	public static void main(String[] args) {
		int[] a = {3, 5, 1, 2, 6, 4, 7, 11, 23, 44, 3, 34};
		InsertSort(a);
		System.out.print("直接插入排序:");
		for(int i = 0; i < a.length; i++) {
			System.out.print(a[i] + " ");
		}

		System.out.println();
		int[] b={3, 5, 1, 2, 6, 4, 7, 11, 23, 44, 3, 34};
		shellSort(b);
		System.out.print("希尔排序:");
		for(int i = 0; i < b.length; i++) {
			System.out.print(b[i] + " ");
		}

		System.out.println();
		int[] c={3, 5, 1, 2, 6, 4, 7, 11, 23, 44, 3, 34};
		bubbleSort(c);
		System.out.print("冒泡排序改进版:");
		for(int i = 0; i < c.length; i++) {
			System.out.print(c[i] + " ");
		}

		System.out.println();
		int[] d={3, 5, 1, 2, 6, 4, 7, 11, 23, 44, 3, 34};
		quickSort(d, 0, d.length-1);		
		System.out.print("快速排序:");
		for(int i = 0; i < d.length; i++) {
			System.out.print(d[i] + " ");
		}
		
		System.out.println();
		int[] e={3, 5, 1, 2, 6, 4, 7, 11, 23, 44, 3, 34};
		selectSort(e);
		System.out.print("选择排序:");
		for(int i = 0; i < e.length; i++) {
			System.out.print(e[i] + " ");
		}
		
		System.out.println();
		int[] f={3, 5, 1, 2, 6, 4, 7, 11, 23, 44, 3, 34};
		heapSort(f);
		System.out.print("堆排序:");
		for(int i = 0; i < f.length; i++) {
			System.out.print(f[i] + " ");
		}
	}
}

猜你喜欢

转载自blog.csdn.net/LiangCJP/article/details/82660769
今日推荐