排序(快排,冒泡,堆排序,插入排序,归并排序,选择排序)算法Java实现

package sample;

public class Sort {
	/**
	 * 插入排序:把array[j]插入到0~j-1的有序序列上,j从第二个元素开始,把第一个元素看成有序序列
	 * @param array
	 */
	public static void insertSort(int[] array)
	{
		int key = 0;
		int i = 0;
		for(int j=1;j<array.length;j++) 
		{
			key = array[j];
			i = j-1;
			while(i >= 0 && array[i] > key) //先判断i的值合法,在判断array[i]的值
			{
				array[i+1] = array[i];
				i--;
			}
			//跳出来后,array[i] <= key,array[i+1]已腾出位置
			array[++i] = key; 
		}
	}
	
	/**
	 * 归并:把两个已经有序的序列合并在一块后,依然有序.array[p~q],和array[q+1,r]已经有序
	 * @param array
	 * @param p:第一合并序列的开始位置
	 * @param q:第一个合并系列的结束位置
	 * @param r:第二个合并序列的结束位置
	 */
	private static void merge(int[] array,int p,int q,int r)
	{
		int n1 = q-p+1;//第一个序列的元素个数
		int n2 = r-q;//第二个序列的元素个数
		int [] left = new int[n1+1];
		int [] right =  new int[n2+1];
		for(int i=0;i<n1;i++)
		{
			left[i] = array[p+i];
		}
		for(int i=0;i<n2;i++)
		{
			right[i] = array[q+i+1];
		}
		left[n1] = Integer.MAX_VALUE;//标记序列是否为空
		right[n2] = Integer.MAX_VALUE;
		int i=0;//两个序列的比较索引
		int j=0;
		for(int k=p;k<=r;k++)//注意:总共r-p+1个数。数组从array[p]到array[r]都需要排序,所以结束条件为k<=r
		{
			if(left[i]<=right[j])
			{
				array[k] = left[i];
				i=i+1;
			}
			else
			{
				array[k] = right[j];
				j=j+1;
			}
		}
		
	}
	/**
	 * 归并排序,先分成两个子序列排序,再进行合并,用递归的思想,最后分成每个元素为一序列,当剩两个元素为一序列的时候的开始合并。
	 * @param array
	 * @param p:要比较序列的开始位置
	 * @param r:要比较序列的结束位置
	 * 
	 */
	public static void mergeSort(int[] array,int p,int r)
	{
		int q = 0;//p,r的中间值
		if(p<r)
		{
			/*向上取整用Math.ceil(double a)
			向下取整用Math.floor(double a)*/
			q = (int) Math.floor((p+r)/2.0);
			mergeSort(array,p,q);
			mergeSort(array,q+1,r);
			merge(array,p,q,r);
		}
	}
	
	/**
	 * 冒泡排序:通过array.length-1回排序,通过两两比较,依次交换,把最大的放在最后面。
	 * @param array
	 */
	public static void bubbleSort(int[] array)
	{
		int i=0;//排序要比较的回数,两两需要比较length-1回
		int j=0;//每一回要比较元素的个数
		int temp = 0;
		for(j=0;j<array.length-1;j++)
		{
			for(i=0;i<array.length-j-1;i++)
			{
				if(array[i]>array[i+1])
				{
					temp = array[i];
					array[i] = array[i+1];
					array[i+1] = temp;
				}
			}
		}
	}
	
	//维持堆得性质
	private static  void maxHeapfy(int array[],int i)
	{
		//数组最后一个元素存的heap堆的大小
		int left = 2*i+1; //从零索引开始的堆,子节点的索引和从一索引开始的堆得子节点索引不一样
		int right = 2*i+2;
		int largest = 0;
		int len = array.length - 1;//获取存储堆大小的索引
		//比较array[2i],array[i]
		if(left < array[len] && array[left] > array[i])
		{
			largest = left;
		}
		else
		{
			largest = i;
		}
		//比较array[2i+1],array[i]
		if(right < array[len]  && array[right] > array[largest])
		{
			largest = right;
		}
		if(largest != i)//largest 的值:2i,2i+1;
		{
			int temp =0;
			temp = array[i];
			array[i] = array[largest];
			array[largest] = temp;
			maxHeapfy(array,largest);
		}
	}
	//建堆
	private static void buildHeap(int[] array)
	{
		int len = array.length-1;//获取存储堆大小的索引
		//从最后一个父节点到根节点开始建堆:位置为:(array[len]-1)/2.0向下取整
		int ParentIndex = (int) Math.floor((array[len]-1)/2.0);
		for(int i = ParentIndex;i>=0;i--)
		{
			maxHeapfy(array, i);
		}
	}

	/**
	 * 	堆排序:构建堆,维护堆得性质,进行排序。堆得性质:逻辑上的完全二叉树且父节点的值不下于子节点的值
	 * @param array
	 */
	public static void heapSort(int[] array)
	{
		buildHeap(array);
		int len = array.length-1;//获取存储堆大小的索引
		//从array[1] - array[len]-1开始和
		for(int i = array[len]-1;i>0;i--)
		{
			int temp =0;
			temp = array[0];
			array[0] = array[i];
			array[i] = temp;
			array[len] = array[len]-1;
			maxHeapfy(array, 0);
		}
	}
	
	
	//对子序列进行就地重排
	private static int partition(int [] array,int p,int r)
	{
		int x = 0; //基准元素
		int i = 0;//
		x = array[r];//以最右边元素array[r]为基准元素
		i = p - 1;//已经比较且最后一个比基准元素小的索引,初始值为p-1
		//以array[r]为基准元素对array[p]~array[r-1]进行分类
		for(int j = p;j<r;j++)
		{
			if(array[j]<=x)//a[j]小于等于基准元素,把a[++i]与a[j]互换。
			{
				i=i+1;
				int temp = 0;
				temp = array[i];
				array[i] = array[j];
				array[j] = temp;
			}
		}
		//基准元素和第一个大于基准元素的元素交换,使左边元素比自己小,右边元素比自己大。
		int temp = 0;
		temp = array[i+1];
		array[i+1] = array[r];
		array[r] = temp;
		return i+1;//区分序列的位置
	}
	/**
	 * 先找到合适位置,再递归排序
	 * @param array
	 * @param p
	 * @param r
	 */
	public static void quickSort(int []array,int p,int r)
	{
		int q = 0;
		if(p<r)
		{
			//当q返回的位置的左边或者右边为一个节点的时,递归的最后一个quickSort开始return
			q = partition(array, p, r);
			quickSort(array, p, q-1);//中间位置不用比较
			quickSort(array, q+1, r);
		}
	}
	
	/**
	 * 选择排序
	 * @param array
	 * 
	 */
	public static void selectSort(int []array)
	{
		int min = 0;
		for(int i=0;i<array.length;i++)
		{
			min = array[i];
			for(int j=i;j<array.length;j++)
			{
				if(min>array[j])
				{
					int  temp = min; 
					min = array[j];
					array[j] = temp;
				}
			}
			array[i] = min;
		}
		
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值