Java 常用排序算法实现

1 篇文章 0 订阅
1 篇文章 0 订阅


1、冒泡排序

       (1)基本思想:当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。
      (2)分析:改进代码中,最好的情况下(数组有序),时间复杂度O(n)。最坏O(n2)。因为是两两相邻比较,冒泡排序稳定。
<span style="font-size:14px;">pac</span>kage com.ys.sort;

public class BubbleSort {
	public void bubbleSort(int[] a){
		int i,j;
		for(i = 0; i < a.length;i++){
			for(j = a.length - 1; j > i;j--)
				if(a[j]>a[j-1])
					swap(a,j,j-1);
		}
	}
	public void swap(int[] a,int s,int m){
		int temp = a[s];
		a[s] = a[m];
		a[m] = temp;
	}
}
package com.ys.sort;
/*
 * 冒泡排序优化
 * 待排序序列有序时,不需要继续后面的循环。循环一遍即可。
 * */
public class BubbleSort2 {
	public void bubbleSort(int[] a){
		int i,j;
		boolean flag = true;
		for(i = 0; i < a.length && flag;i++){
			
			flag = false; 			
			for(j = a.length - 1; j > i;j--)
				if(a[j]>a[j-1]){
					swap(a,j,j-1);
					flag = true;
				}					
		}
	}
	public void swap(int[] a,int s,int m){
		int temp = a[s];
		a[s] = a[m];
		a[m] = temp;

2、选择排序

      (1)基本思想:选择排序是从待排序的数中选出最小的放在已经排好的后面。
     (2)时间复杂度O(n2),最大的特点是交换移动数据次数相对少。不稳定。
package com.ys.sort;

public class SelectSort {  
	   
    public  void selectSort(int[] a) {  
        int i, j, min;  
        for (i = 0; i < a.length - 1; i++) {  
            min = i;  
            for (j = i + 1; j < a.length; j++){  
                if (a[j] < a[min])  
                    min = j; 
            }
            
            if (min != i)   
            	swap(a,i,min);    
        }  
    }
    public void swap(int[] a,int s,int m){
		int temp = a[s];
		a[s] = a[m];
		a[m] = temp;
	}
}


3、插入排序

(1)基本思想:将一个记录插入到已经排好序的有序表中。
(2)思路上从待排序的数据中选出一个,插入到前面合适的位置,耗时点在插入方面,合适的位置意味着我们需要进行比较找出哪是合适的位置,举个例子:对于9,2,7,19,100,97,63,208,55,78这组数,第一个数9前面没有,不做操作,当第一个数完后,剩下的数就是待排序的数,我们将要从除去9开始的数中选出一个插入到前面合适的位置,拿到2后,2比9小,放在temp上,通过循环找出这个合适的位置,发现比temp大的数,立即将该数向后移动一位(这样做的目的是:前面需要空出一位来进行插入),最后通过注释3处的代码将数插入。

 (3)本排序适合:基本有序的数据。好的情况下,时间复杂度O(n),平均和最坏都是O(n2)。

package com.ys.sort;
public class InsertSort {
	
	public void insertSort(int[] a){
		int i,j;
		int temp = 0;
		for(i=1;i<a.length;i++){
			if(a[i]<a[i-1]){
				temp = a[i];
				for(j = i-1;j >=0 && a[j] > temp;j--)
					a[j+1] = a[j];
				a[j+1] = temp;
			}
		}
	}
}


4、堆排序

     (1)堆是一个完全二叉树。堆分为两种,大顶堆和小顶堆(最小堆、小根堆)。大顶堆就是堆顶元素是整个堆中最大的,每个结点的值都大于或等于其左右孩子结点。小顶堆的意思是堆顶元素是整个堆中最小的,每个结点的值都小于或等于其左右孩子结点的值。
     (2)算法的过程:第一步,建堆,从一个数组顺序读取元素,建立一个堆(假设大顶堆)
                             第二步,堆顶元素出堆,即将堆顶元素和堆底元素交换,堆中的最大值放到了数组最后。重新调整堆使其成为大顶堆。
    (3)最好、最坏和平均时间复杂度为O(nlogn),不稳定。
        初始构建堆所需比较次数较多,并不适合待排序序列个数较少的情况。

package com.ys.sort;

import java.util.Arrays;
/*
 * 利用《大话数据结构》堆排序进行修改
 * 注意java中数组从0开始,节点s对应左右孩子是2s+1,2s+2; 
 * */


public class HeapSort2 {
	
	public void heapSort(int[] array){
		maxHeapAdjust(array);    //构建成大顶锥
		
		for(int i=array.length-1;i>0;i--){
			swap(array,0,i);
			heapAdjust(array,0,i-1);  //重新调整为大顶堆
		}
	}
	public void maxHeapAdjust(int[] array){
		for(int i=array.length/2;i>=0;i--){//构建成大顶锥
			heapAdjust(array,i,array.length-1);
		}
	}
	public void heapAdjust(int[] a,int s,int m){
		int temp,i; 
		temp = a[s]; //表示第s个节点
		for(i=2*s+1;i<=m;i=2*i+1){
			if(i<m && a[i]<a[i+1])
				++i;
			if(temp>=a[i])
				break;
			a[s] = a[i];
			s = i;
		}
		a[s] = temp;  
	}
	public void swap(int[] array,int from,int to){
		int temp;
		temp = array[from];
		array[from] = array[to];
		array[to] = temp;
	}

	public static void main(String[] args) {
		HeapSort2 h = new HeapSort2();
		int[] a= {2,16, 14, 10, 8, 7, 9, 3,13, 4};
		h.heapSort(a);
		String intArrayString = Arrays.toString(a); //将数组转换为字符串打印输出 
		System.out.print(intArrayString);

	}
}


5、归并排序

(1)利用归并的思想实现的排序方法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
(2)基本思路就是将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序。如何让这二组组内数据有序了?可以将A,B组各自再分成二组。依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。这样通过先递归的分解数列,再合并数列就完成了归并排序。
(3)时间复杂度O(nlogn),空间复杂度O(n+logn)。稳定
package com.ys.sort;

import java.util.Arrays;

public class MergeSort {
	//归并排序
    public static void mergeSort(int[] arr){
        int[] temp =new int[arr.length];
        msort(arr, temp, 0, arr.length-1);
    }
    private static void msort(int[] a, int[] b, int left, int right){
        //当left==right的时,已经不需要再划分了
        if (left<right){
            int middle = (left+right)/2;
            msort(a, b, left, middle);          //左子数组
            msort(a, b, middle+1, right);       //右子数组
            merge(a, b, left, middle, right);    //合并两个子数组
        }
    }
    // 合并两个有序子序列 arr[left,..., middle] 和 arr[middle+1,..., right]。temp是辅助数组。
    private static void merge(int arr[], int temp[], int left, int middle, int right){
        int i=left;     
        int j=middle+1;
        int k=0; 
        while ( i<=middle && j<=right){
            if (arr[i] <=arr[j]){
                temp[k++] = arr[i++];
            }
            else{
                temp[k++] = arr[j++];
            }
        }
        while (i <=middle){
            temp[k++] = arr[i++];
        }
        while ( j<=right){
            temp[k++] = arr[j++];
        }
        //把数据复制回原数组
        for (i=0; i<k; ++i){
            arr[left+i] = temp[i];
        }
    }
	public static void main(String[] args) {
		int[] a={5,6,8,9,7,8,8,8,3,10};
		mergeSort(a);
		String intArrayString = Arrays.toString(a); //将数组转换为字符串打印输出 
		System.out.print(intArrayString);
	}
}


6、快速排序

(1)基本思想:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,达到排序目的。
(2)最好和平均O(nlogn),最坏O(n2)。空间复杂度最好O(logn),最坏O(n)。
package com.ys.sort;

import java.util.Arrays;

public class QuickSort {

	public void quickSort(int[] a){
		qSort1(a,0,a.length-1);
	}
	public void qSort1(int[] a,int low,int high){
		int pivot;
		while(low<high){
			pivot = partition1(a,low,high);//枢轴值,左边的值比它小,右边的值比它大
			qSort1(a,low,pivot-1);
			low = pivot + 1;
		}
	}
	/*
	 * 取得枢轴值
	 * */
	public int partition1(int[] a,int low,int high){
		pivotSort(a,low,high);
		int pivotkey =a[low];
		int temp = pivotkey;
		while(low<high){
			while(low<high && a[high]>=pivotkey)
				high--;
			a[low] = a[high];
			while(low<high && a[low]<=pivotkey)
				low++;
			a[high] = a[low];
		}
		a[low] = temp;
		return low;
				
	}
/*
 * 三数取中,优化选取枢轴值
 * */	
	public void pivotSort(int[] a,int low,int high){
		int m = low + (high-low)/2;
		if(a[low]>a[high])
			swap(a,low,high);
		if(a[m]>a[high])
			swap(a,m,high);
		if(a[m]>a[low])
			swap(a,m,low);
	}
	public void swap(int[] a,int s,int t){
		int temp = a[s];
		a[s] = a[t];
		a[t] = temp;
	}
	public static void main(String[] args) {
		int[] a={5,6,8,9,7,4,1,2,3};
		QuickSort m = new QuickSort();
		m.quickSort(a);
		String intArrayString = Arrays.toString(a); //将数组转换为字符串打印输出 
		System.out.print(intArrayString);
	}
}
本文中图片和部分解释转载自http://blog.csdn.net/zhangerqing/article/details/8831542

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值