java 数据结构学习之(二) 简单排序

冒泡排序最经典:

public void BubbleSort1(){

		for (int i = nElement - 1; i > 0; i--) {
			for (int j = 0; j < i; j++) {
				if(arr[j] > arr[j+1]){
					swap(j,j+1);
				}
			}
		}
	}

private void swap(int a,int b){
	    arr[a] = arr[a] + arr[b];
		arr[b] = arr[a] - arr[b];
		arr[a] = arr[a] - arr[b];
	}

 

以下是冒泡排序排序的改进版本:

 

/**(优化后的冒泡排序)
	 * 双向冒泡排序 
	 * ps: 获取最大的数放在最右边后,回头获取最小的数放在最左边。以此类推,外层循环次数 n / 2,貌似比单向冒泡快一点。
	 */
	public void BubbleSort2(){
		int i,j,k,left = 0,right = nElement - 1;
		for (i = nElement/2; i > 0; i--) {
			for (j = left; j < right; j++) {
				if(arr[j] > arr[j+1]){
					swap(j,j+1);
				}
			}
			for (k = right - 1; k > left; k--) {
				if(arr[k] < arr[k - 1] ){
					swap(k,k - 1);
				}
			}
			left++;
			right--;
		}
	}
	
	/**(优化后的冒泡排序)
	 * ps:如果 有一次比较没有做任何数据移动,说明已经排好序了,可以结束比较了。
	 */
	public void BubbleSort3(){
		boolean isSorted = false;
		for (int i = nElement - 1; i > 0 && !isSorted; i--) {
			isSorted = true;//假设已经排好序
			for (int j = 0; j < i; j++) {
				if(arr[j] > arr[j + 1]){
					swap(j,j + 1);
					isSorted = false;
				}
			}
		}
	}
	
	/**(优化后的冒泡排序)
	 * ps:记录最后一次交换位置,这样就可以确定到底那些区域还没有排好序,缩小比较范围。
	 */
	public void BubbleSort4(){
		int lastIndex = nElement - 1,j=0;
		while(lastIndex > 0){
			for (int i = j = 0; i < lastIndex; i++) {
				if(arr[i] > arr[i + 1]){
					swap(i, i+1);
					j = i;
				}
			}
			lastIndex = j;
		}
	}

 

其中BubbleSort2减少了每次比较的次数,提高了效率。而3,4这两个方法也是同样的原理,减少了可能会做的无用功。

 

下面是选择排序,这个排序是通过减少移动数组的次数来提高效率的。

 

public void selectSort() {
		for (int i = 0; i < nElement - 1; i++) {
			int k = i;
			for (int j = i + 1; j < nElement; j++) {
				if (arr[k] > arr[j]) {
					k = j;
				}
			}
			if (k != i) {
				swap(k, i);
			}
		}
	}

 

最后是选择排序,这个排序比冒泡排序应该要快一倍,比选择排序要快一点。如果是倒序排序的话,则可能没有优势,在基本有序的情况下还是可以的。

 

public void insertSort(){
		int repeat = 0,t = 0;
		for (int i = 1; i < nElement; i++) {
			int j = i;
			while (j > t && arr[i] <= arr[j - 1]){
				//发现重复值 设置为-1
				if(arr[i]==arr[j - 1]){
					arr[i] = -1;
					repeat++;
				}
				--j;
			}
			t = repeat;
			if(j < i){
				int temp = arr[i];
				for (int k = i; k > j; k--) {
					arr[k] = arr[k - 1];
				}
				arr[j] = temp;
			}
		}
		if(repeat > 0){
			nElement = nElement - repeat;
			for (int i = 0; i < nElement; i++) {
				arr[i] = arr[i + repeat];
			}
		}
		
	}

上面这个排序还加了个删除重复值的功能。

 

另外一种实现,感觉没有上面的效率高

 

public void insertSort2(){
		for (int i = 1; i < nElement; i++) {
			int j = i;
			int temp = arr[i];
			while(j > 0 && temp < arr[j - 1]){
				arr[j] = arr[--j];
			}
			arr[j] = temp;
		}
	}

效率没有第一种高的环境是在倒序的情况下,因为这个环境下移动的次数比较多,原来分开移动没有一次性移动快。其他情况下是差不多的。

下面贴出所有的代码

 

package sort;

public class Sort {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Sort o = new Sort(10000);
		for (int i = 10; i > 0; i--) {
			o.insert(i);
		}
		o.insert(9);
		o.insert(8);
		/*for (int i = 0; i < 10000; i++) {
			o.insert(i);
		}*/
		long begin = System.currentTimeMillis();
		o.insertSort();
		long end = System.currentTimeMillis();
		System.out.println("time="+(end - begin));
		o.display();
	}

	private int[] arr = null;
	private int nElement = 0;//当前数组的实际长度
	public Sort(int size){
		this.arr = new int[size];
		this.nElement = 0;
	}
	
	public int[] getArr(){return this.arr;}
	
	/**插入
	 * @param c
	 */
	public void insert(int c){
		arr[nElement++] = c;
	}
	
	public void BubbleSort1(){
		for (int i = nElement - 1; i > 0; i--) {
			for (int j = 0; j < i; j++) {
				if(arr[j] > arr[j+1]){
					swap(j,j+1);
				}
			}
		}
	}
	
	/**(优化后的冒泡排序)
	 * 双向冒泡排序 
	 * ps: 获取最大的数放在最右边后,回头获取最小的数放在最左边。以此类推,外层循环次数 n / 2,貌似比单向冒泡快一点。
	 */
	public void BubbleSort2(){
		int i,j,k,left = 0,right = nElement - 1;
		for (i = nElement/2; i > 0; i--) {
			for (j = left; j < right; j++) {
				if(arr[j] > arr[j+1]){
					swap(j,j+1);
				}
			}
			for (k = right - 1; k > left; k--) {
				if(arr[k] < arr[k - 1] ){
					swap(k,k - 1);
				}
			}
			left++;
			right--;
		}
	}
	
	/**(优化后的冒泡排序)
	 * ps:如果 有一次比较没有做任何数据移动,说明已经排好序了,可以结束比较了。
	 */
	public void BubbleSort3(){
		boolean isSorted = false;
		for (int i = nElement - 1; i > 0 && !isSorted; i--) {
			isSorted = true;//假设已经排好序
			for (int j = 0; j < i; j++) {
				if(arr[j] > arr[j + 1]){
					swap(j,j + 1);
					isSorted = false;
				}
			}
		}
	}
	
	/**(优化后的冒泡排序)
	 * ps:记录最后一次交换位置,这样就可以确定到底那些区域还没有排好序,缩小比较范围。
	 */
	public void BubbleSort4(){
		int lastIndex = nElement - 1,j=0;
		while(lastIndex > 0){
			for (int i = j = 0; i < lastIndex; i++) {
				if(arr[i] > arr[i + 1]){
					swap(i, i+1);
					j = i;
				}
			}
			lastIndex = j;
		}
	}
	
	/**
	 * 奇偶排序 
	 * 第一次比较奇数对,第二次比较偶数对。
	 * 听说如果是多处理器这样排序效率高 
	 */
	public void OddEvenSort(){
		boolean isSorted = false;int i=0;
		while(!isSorted){
			i++;
			isSorted = OddOrEventSort(0) || OddOrEventSort(1);
		}
		System.out.println(i);
	}
	
	private boolean OddOrEventSort(int i){
		boolean isSorted = true;
		for (int j = i; j < nElement - 1; j+=2) {
			if(arr[j] > arr[j+1]){
				swap(j, j+1);
				isSorted = false;
			}
		}
		return isSorted;
	}
	
	public void insertSort(){
		int repeat = 0,t = 0;
		for (int i = 1; i < nElement; i++) {
			int j = i;
			while (j > t && arr[i] <= arr[j - 1]){
				//发现重复值 设置为-1
				if(arr[i]==arr[j - 1]){
					arr[i] = -1;
					repeat++;
				}
				--j;
			}
			t = repeat;
			if(j < i){
				int temp = arr[i];
				for (int k = i; k > j; k--) {
					arr[k] = arr[k - 1];
				}
				arr[j] = temp;
			}
		}
		if(repeat > 0){
			nElement = nElement - repeat;
			for (int i = 0; i < nElement; i++) {
				arr[i] = arr[i + repeat];
			}
		}
		
	}
	
	public void insertSort2(){
		for (int i = 1; i < nElement; i++) {
			int j = i;
			int temp = arr[i];
			while(j > 0 && temp < arr[j - 1]){
				arr[j] = arr[--j];
			}
			arr[j] = temp;
		}
	}
	
	public static void insertSort(int[] elements){ 
        for(int i = 1;i <elements.length; i++){ 
            int j = -1; 
            while(j <= i && elements[i] > elements[++j]);//找到element[i]应该摆放的位置,此处可以利用查找算法进行优化 
            if(j < i){ 
                //将j之后的数据移动一位,然后把elements[i]移动到j处 
                int temp = elements[i]; 
                for(int k = i-1;k >= j;k--){ 
                    elements[k+1] = elements[k]; 
                } 
                elements[j] = temp; 
            } 
        } 
}
	
	public void selectSort() {
		for (int i = 0; i < nElement - 1; i++) {
			int k = i;
			for (int j = i + 1; j < nElement; j++) {
				if (arr[k] > arr[j]) {
					k = j;
				}
			}
			if (k != i) {
				swap(k, i);
			}
		}
	}
	public void display(){
		for (int i = 0; i <nElement; i++) {
			System.out.println(arr[i]);
		}
	}
	
	private void swap(int a,int b){
	    arr[a] = arr[a] + arr[b];
		arr[b] = arr[a] - arr[b];
		arr[a] = arr[a] - arr[b];
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值