java冒泡排序、插入排序、快速排序、选择排序、堆排序

package suanfa;
/**
 * @author lackiechan
 *
 */
public class Sort {
	/**
	 * 插入排序 稳定性:稳定  时间复杂度(n2)
	 * 1、直接插入排序法
	 * 算法思想:1、把n个要排序的数组看成一个含有1个已排序有序表和一个含有n-1个未排序的元素的无序表
	 *         2、从无序表中取出第i(取n-1次)个元素,将它和有序表中的元素进行比较 
	 *         3、把该元素查到已排序的序列表中形成新的有序表
	 *         4、重复n-1次即可完成插入排序
	 *         假如把直接插入排序应用于链表存储结构不用移动元素,而是修改指针
	 *         插入排序是稳定 即:插入相等的值是插入有序表的后面 没有改变原来的排序
	 * @param arr 这是传入的数组
	 * @return int[] 返回排好序的数组
	 */
	public static int[] insertSort(int... array){  //直接插入排序
		int temp;//第i趟拿出来比较的数
		int j;//内循环 
		for(int i=1;i<array.length;i++){//取(数组长度-1)趟
			temp=array[i];//把取出的元素作为和有序表比较,temp为取出来的元素		
			for(j=i;j>0&&temp<array[j-1];j--){//j为内循环的参考值    for循环也可以用j=i; while(j>0&&temp<array[j-1]) {array[j]=array[j-1];; j--;}代替
				array[j]=array[j-1];//元素右移动一位
			}
			array[j]=temp;//把该元素插到指定的位置                             
		}    
		return array;	
	}
	/**折半排序:是直接插法的改进
	 * 		在理解直接插入排序的前提下:
	 *       把有序表进行折半和无序表中拿出的元素比较 提高查找效率
	 * @param array
	 * @return
	 */
	public static int[] halfInsertSort(int... array){
		int temp;//第i趟拿出来比较的数   哨兵
		for(int i=1;i<array.length;i++){
			temp=array[i];
			int low=0;
			int high=i-1;
			while(low<=high){
				int middle=(low+high)/2;
				if(temp<array[middle]){
					high=middle-1;
				}
				else low=middle+1;
			}
			for(int j=i;j>high+1;j--){ //把要插入位置和它后面的元素全部后移一位  然后把元素插到该位置
				array[j]=array[j-1];//后移动一位
			}
			array[high+1]=temp;//high+1为要插入的位置
		}
		return array;
	}

		/**
		 * 希尔排序  稳定性:不稳定  时间复杂度O(nlogn)
		 * 希尔排序也是一种插入排序方法,实际上是一种分组插入方法
		 * 先取一个小于n的整数d1作为一个增量,把表的全部记录分成d1个组,所有
		 * 距离为d1的倍数的记录放在同一个组中,在各组内进行直接插入排序,然后
		 * ,取第二个增量d2(<d1),重复上述的分组和排序,直至所取的dt=1,即所有
		 * 记录放在同一组中进行直接插入排序为止
		 */
	public static int[] shellSort(int... array){				
				int gap = array.length/2;
				int temp;
				while(gap>0){
					for(int i=gap;i<array.length;i++){
						temp = array[i];
						int j = i - gap;
						while(j>=0 && temp < array[j]){
							array[j+gap] = array[j];
							j = j - gap;
						}
						array[j+gap] = temp;
					}
					gap = gap/2; 
				}
				return array;
			}
	/**
	 * 冒泡排序 稳定性:稳定 时间复杂度O(n2)
	 * 冒泡排序
	 * 算法思想:每排一趟大的沉下去 第i趟大第i大的沉下来
	 * @param array
	 * @return
	 */
	public static int[] bubbleSort(int... array){
		for(int i=0;i<array.length-1;i++){
			for(int j=0;j<array.length-1-i;j++){
				if(array[j]>array[j+1]){
					int temp=array[j+1];
					array[j+1]=array[j];
					array[j]=temp;
				}
			} 
		}
		return array;
	}
	/**返回快速排序 区轴的位置
	 * @param low
	 * @param high
	 * @param array
	 * @return
	 */
	public static int quickSortLocation(int low,int high,int... array){
		int pivotkey=array[low];
		while(low<high){
			while(low<high&&array[high]>=pivotkey) high--;//当高位指针的值比参考元素的值大时 指针向左移动一位(即向左扫描)
			array[low]=array[high];//当高位指针的值比参考元素的值小时,把高位指针的值移到low位
			while(low<high&&array[low]<=pivotkey)low++;//当低位指针的值比参考元素的值小时 指针向右移动一位(即向右扫描)
			array[high]=array[low];//当低位指针的值比参考元素的值大时,把低位指针的值移到high位
		}
		array[low]=pivotkey;	
		return low;
	}
	/**
	 * 快速排序 稳定性:不稳定 时间复杂度O(nlogn)
	 *      算法思想: 在R[low..high]中任选一个记录作为基准(Pivot),
	 *      以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1)和R[pivotpos+1..high],
	 *      并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,
	 *      右边的子区间中所有记录的关键字均大于等于pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。
	 * @param low
	 * @param high
	 * @param array
	 * @return
	 */
	public static int[] quickSort(int low,int high,int... array){
		if(low<high){
			int pivotLoc=quickSortLocation(low,high,array);
			quickSort(pivotLoc+1,high,array);
			quickSort(low,pivotLoc-1,array);
		}
		return array;		
	}	
	/**
	 * 选择排序稳定性: 不稳定 时间复杂度O(n2)
	 * 选择排序
	 * 		算法思想:在每第i趟在n-i+1个记录中选出最小值作为有序序列的第i个记录
	 *     (和简单插入排序有点像左边是有序表 不过选择插入是将无序表中最小值直接插到有序表的最后位置)
	 * @param array
	 * @return
	 */
	public static int[] selectSort(int... array){
		for(int i=0;i<array.length-1;i++){//需选择n-1趟
			for(int j=i+1;j<array.length;j++){
				if(array[i]>array[j]){
					int temp=array[i];
					array[i]=array[j];
					array[j]=temp;
				}
			}
		}
		return array;
	}
	/**调整堆为大顶堆
	 * @param array
	 * @param index
	 * @param last
	 */
	public static void heapAdjust(int[] array,int index,int last){//树的根节点记为1 所以数组的第一个数array[0] 没有参加排序
		int temp=array[index];  
		for(int j=2*index;j<=last;j*=2){//
			if(j<last&&array[j]<array[j+1]) ++j;//左右右子树比较 若右子树大则j加1  这个作用主要是 想默认array[j]大 方便和index的值比较
			if(temp>array[j])break;//若temp大则跳出循环把他插入index
			array[index]=array[j];//大的值替换到index位置
			index=j;			
		}
		array[index]=temp;
	}
	
	/**
	 * 堆排序稳定性 不稳定 时间复杂度O(nlogn) 
	 * 堆排序
	 * @param array
	 * @return
	 */
	public static int[] heapSort(int... array){
		for(int i=(array.length-1)/2;i>0;--i)
			heapAdjust(array,i,array.length-1);
		for(int i=array.length-1;i>1;--i){
			int temp=array[i];//最后一个记录相互交换
			array[i]=array[1];
			array[1]=temp;
			heapAdjust(array,1,i-1);//重新调整为大顶堆
		}
		return array;
	}
	/**归并排序
	 * @param array
	 * @return
	 */
	public static int[] megreSort(int... array){
		
		return array;
	}
	
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值