常用排序总结

总结一下面试当中经常问到的排序算法:

1、冒泡排序:

package com.zj.sort;

public class MaoPaoSort {
	
	public void Sort(int[] array){	//冒泡程序主要是冒泡的过程,两两交换
		for(int i= 0 ;i<array.length;i++){
			for(int j= array.length-1;j>=i+1;j--){
					if(array[j] < array[j-1]){
						int tmp = array[j];
						array[j] = array[j-1];
						array[j-1] = tmp;
				}
			}
		}
		
	}
	
	
	public static void main(String[] arqs){
		int[] test = new int[]{3,4,1,2,1,3,6,5,4};
		MaoPaoSort ms = new MaoPaoSort();
		ms.Sort(test);
		
		for(int i=0;i<test.length;i++){
			System.out.println(String.format("第%d个数字:%d", i,test[i]));
		}
	}

}

冒泡排序最坏的情况是54321要排成12345。考虑这种情况的算法复杂度O() = n*(n-1)+(n-1)*(n-2)+.....+2*1=O(n^2)

最好的情况呢?尼玛,好像我的写法没有最好的情况。。。原来数组12345排成12345,复杂度也是O(n^2)


2、快速排序:

package com.zj.sort;


public class QuickSort {	//递归调用,每递归一次将数组分成三段:left_sub_array,array[i],right_sub_array
							//选择标称值很关键,影响效率;下面的算法partition函数效率上做了优化
	
	public void MyQuickSort(int[] array){
		quicksort(array, 0, array.length-1);
	}
	
	public void quicksort(int[] array,int left,int right){
		if(left < right){
			int q = partition(array,left,right);
			quicksort(array, left, q-1);
			quicksort(array, q+1, right);
		}
	}
		
	public int partition(int[] array,int left,int right){
		int x = array[right];
		int i = left -1;
		for(int j = left;j<=right;j++){
			if(array[j] < x && i < j){
				i++;
				if(i != j){
					int k = array[j];
					array[j] = array[i];
					array[i] = k;
				}
			}
		}
		
		int k = array[right];
		array[right] = array[i+1];
		array[i+1] = k;
		
		return i+1;
		
	}
	
	public static void main(String[] arqs){
		int[] test = new int[]{2,4,1,5,6,8,2,0};
		
		QuickSort qs = new QuickSort();
		qs.MyQuickSort(test);
		for(int i=0;i<test.length;i++){
			System.out.println(String.format("第%d个数字:%d", i,test[i]));
		}
	}
	
}
快速排序影响效率的是数组分left_sub_array,array[i+1],right_sub_array的过程。i表示由于array[i+1]的子数组的最后一个索引。代码中将array[i+1]的值设为array[right],不过赋值的过程在最后,因为i的索引位置到最后才确定;i的初始值为left-1,假设left_sub_array为空;后面慢慢将right_sub_array中小于x的值移到left_sub_array中(移动的过程中同时i++,即增到left_sub_array的长度)

代码中我们初始假设left_sub_array为空,所以对应的算法的最坏情况就是,数组都小于等于x的情况(把right_sub_array中的数据搬移到left_sub_array中);这种情况会进入if,执行i++操作,但不会执行交换操作,复杂度O(n);再考虑递归:O(n)=O(n-1)+c.N;O(n)=O(1)+c(2+3+4....+N)=O(n^2);

快速排序的平均算法复杂度比较难推到,记得是O(n.logn)

3、堆排序

package com.zj.sort;

public class HeapSort {	//堆排序,通过递归调用将最大的元素放到堆顶;有构造最大堆的过程,还有最大堆更新的过程
	
	private int dataLen;

	public void Sort(int[] array) {
		dataLen = array.length;
		buildMaxHeap(array);
		for(int i=dataLen -1;i>=1;i--){
			int k = array[i];
			array[i] = array[0];
			array[0] = k;
			dataLen--;
			max_heapify(array, 0);
		}
	}

	public void max_heapify(int[] data, int i) {
		int child_l = 2 * i + 1;
		int child_r = 2 * (i + 1);
		
		int largest =i;
		
		if(child_l < dataLen && data[child_l] > data[largest])
				largest = child_l;
		if(child_r <dataLen && data[child_r]> data[largest])
				largest = child_r;
		
		if(largest != i){
			int k = data[i];
			data[i] = data[largest];
			data[largest] = k;
			max_heapify(data, largest);
		}
		
	}

	public void buildMaxHeap(int[] data) {
		for(int i = (dataLen-1)/2;i >=0;i--){
			max_heapify(data, i);
		}
	}
	
	public static void main(String[] arqs){
		int[] test = new int[]{3,1,4,6,2,3,7,1,9};
		HeapSort hs = new HeapSort();
		hs.Sort(test);
		
		for(int i=0;i<test.length;i++){
			System.out.println(String.format("第%d个数字:%d", i,test[i]));
		}
		
	}

}

4、计数排序

package com.zj.sort;

public class CountSort {	//计数排序需要知道数组的值范围,然后用散列表的形式记录值的位置	
							//效率高的情况:值分布密集,(下列算法可以优化:如果值密集的分布在900~1000,散列算法可以优化,节约内存)
	
	public int[] Sort(int[] data,int max_limit){
		int[] tmp = new int[max_limit];
		int[] des = new int[data.length];
		for(int i=0;i<data.length;i++){
			tmp[data[i]] +=1;
		}
		
		for(int j = 1;j<max_limit;j++){
			tmp[j] +=tmp[j-1];	//数字x在数组中的位置
		}
		
		for(int i=0;i<data.length;i++){
			des[tmp[data[i]]-1] = data[i];
			tmp[data[i]] --;
		}
		
		return des;
	}
	
	public static void main(String[] arqs){
		int[] test = new int[]{4,1,5,2,7,3,8};
		CountSort cs = new CountSort();
		test = cs.Sort(test, 20);
		
		for(int i =0;i<test.length;i++){
			System.out.println(String.format("第%d个位置:%d", i,test[i]));
		}
		
	}
	
}
5、桶排序

package com.zj.sort;

public class BucketSort {	//均匀分布 0~20之间	适用于均匀分布,hash表的类似 实现,效率高的情况是链表长度均匀
	
	public static void main(String[] arqs){
		int[] test = new int[]{2,2,1,4,3,6,5,7,8,6,9,13,12,15,17,18};
		
		BucketSort bs = new BucketSort();
		test =bs.Sort(test);
		for(int i=0;i<test.length;i++){
			System.out.println(String.format("第%d个数字:%d", i,test[i]));
		}
	}
	
	public int[] Sort(int[] array){
		int[] des = new int[array.length];
		Bucket[] tmp = new Bucket[5];
		for(int i =0;i<tmp.length;i++)
			tmp[i] = new Bucket(0, null);
		
		for(int i=0;i<array.length;i++){
			Bucket bucket = new Bucket(array[i], null);
			bucket_into_sort(tmp[(array[i]/4)], bucket);
		}
		
		int j=0;
		for(int i=0;i<tmp.length;i++){
			Bucket k = tmp[i];
			k = k.next;
			while(k !=null){
				des[j++] = k.value;
				k = k.next;
			}
		}
		
		return des;
		
	}
	
	public void bucket_into_sort(Bucket src_bucket,Bucket bucket){
		Bucket tmp = src_bucket.next;
		if(tmp == null){
			src_bucket.next = bucket;
			return;
		}
		while(tmp != null){
			if(tmp.value > bucket.value){
				bucket.next = tmp;
				src_bucket.next = bucket;
				return;
			}
			src_bucket = src_bucket.next;
			tmp = tmp.next;
		}
		src_bucket.next = bucket;
		
	}

}


class Bucket{
	public int value;
	public Bucket next;
	public Bucket(int value,Bucket bucket){
		this.value = value;
		this.next = bucket;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值