zoukankan      html  css  js  c++  java
  • 常用排序算法

    1、选择排序(时间复杂度为O(n2))

    选择排序的思想是在线性表中找到最小数,并将其放在表头,然后在剩下的数中找到最小数,放在第一个数之后,直到线性表中仅剩下一个数为止。

    Java实现:

      public static void choiceSort(Integer[] a) {
    		if (a == null || a.length <= 0) {
    			return;
    		}
    		for (int i = 0; i < a.length; i++) {
    			int min = i; /* 将当前下标定义为最小值下标 */
    			for (int j = i + 1; j < a.length; j++) {
    				if (a[min] > a[j]) { /* 如果有小于当前最小值的关键字 */
    					min = j; /* 将此关键字的下标赋值给min */
    				}
    			}
    			if (i != min) {/* 若min不等于i,说明找到最小值,交换 */
    				int tmp = a[min];
    				a[min] = a[i];
    				a[i] = tmp;
    			}
    		}
    	}
    

      

    2、插入排序(时间复杂度为O(n2))

    插入排序的思想是在已经排好的子数组中反复插入一个新的元素,直到整个数组全部排好序。

    Java实现:

      public static void insertSort(int[] arr) {
    		for (int i = 1; i < arr.length; i++) {
    			if (arr[i - 1] > arr[i]) {
    				int temp = arr[i];// 待插入的元素
    				int j = i;
    				while (j > 0 && arr[j - 1] > temp) {// 将大于temp的往后移一位
    					arr[j] = arr[j - 1];
    					j--;
    				}
    				arr[j] = temp;
    			}
    		}
    	}
    

      

    3、冒泡排序(时间复杂度O(n2))

    冒泡排序的思想是在每次遍历中,比较连续相邻的元素,如果某一对元素是降序,则互换它们的值;否则保持不变。第一次遍历后,最后一个元素成为数组中的最大数。第二次遍历之后,倒数第二个元素成为数组中的第二大数。整个过程持续到所有元素都已排序好。

    注意:如果在某次遍历中没有发生变换,那么就不必进行下一次遍历,因为所有的元素都已经排好序了。

    Java实现:

      public static void bubbleSort(int[] list){
    		boolean needNextPass = true;
    		
    		for(int k = 1; k < list.length && needNextPass; k++){
    			needNextPass = false;
    			for(int i = 0; i < list.length - k; i++){
    				if(list[i] > list[i+1]){
    					int temp = list[i];
    					list[i] = list[i + 1];
    					list[i + 1] = temp;
    					needNextPass = true;
    				}
    			}
    		}
    	}
    

      

    4、快速排序(时间复杂度O(nlogn))

    快速排序的思想是在数组中选择一个主元的元素,将数组分为两个部分,使得第一部分中的所有元素都小于或者等于主元,而第二部分中的所有元素都大于主元。对第一部分递归地应用快速排序算法,然后对第二部分递归地应用快速排序算法。

    Java实现:

    /*
     * 调用划分函数,使得子数组顺序重排
     */
    void quick_sort(int A[], int p, int r){
        if(p < r){
            int q = partition(A, p, r);
            quick_sort(A, p, q-1);
            quick_sort(A, q+1, r);
        }
    }
    
    /*
     * 对于比x值小的元素通过交换放置到小于x值的区域。
     * 最后将大于x值的区域的第一个元素与x值,即原A[r],交换
     * 该下标即为q,形成两个符合要求的数组(A[p..q-1]的元素都不大于A[q],A[q+1..r]都不小于A[q])
     */
    int partition(int A[], int p, int r){
        int x = A[r];
        int i = p - 1;
        int j;
        for(j = p; j <= r-1; j++){
            if(A[j] <= x){
                i++;
                int temp = A[i];
                A[i] = A[j];
                A[j] = temp;
            }
        }
        int temp = A[i+1];
        A[i+1] = A[r];
        A[r] = temp;
        return i+1;
    }
    

      

      

      

    5、归并排序(时间复杂度O(nlogn))

    归并排序的思想是将数组分为两半,对每部分递归地应用归并排序。在两个部分都拍好序后,对它们进行归并。

    Java实现:

      public static void mergeSort(int[] list) {
    		if (list.length > 1) {
    			int[] firstHalf = new int[list.length / 2];
    			System.arraycopy(list, 0, firstHalf, 0, list.length / 2);
    			mergeSort(firstHalf);
    
    			int secondHalfLength = list.length - list.length / 2;
    			int[] secondHalf = new int[secondHalfLength];
    			System.arraycopy(list, list.length / 2, secondHalf, 0,
    					secondHalfLength);
    			mergeSort(secondHalf);
    
    			int[] temp = merge(firstHalf, secondHalf);
    			System.arraycopy(temp, 0, list, 0, temp.length);
    		}
    	}
    
    	public static int[] merge(int[] list1, int[] list2) {
    		int[] temp = new int[list1.length + list2.length];
    
    		int pos1 = 0;
    		int pos2 = 0;
    		int pos3 = 0;
    
    		while (pos1 < list1.length && pos2 < list2.length) {
    			if (list1[pos1] < list2[pos2])
    				temp[pos3++] = list1[pos1++];
    			else
    				temp[pos3++] = list2[pos2++];
    		}
    
    		while (pos1 < list1.length)
    			temp[pos3++] = list1[pos1++];
    
    		while (pos2 < list2.length)
    			temp[pos3++] = list2[pos2++];
    
    		return temp;
    	}
    

    6、堆排序(时间复杂度O(nlogn)) 

    堆排序是将数据存储在堆中,其中堆是一棵具有如下属性的二叉树:

    1.它是一棵完全二叉树

    2.每个节点大于或者等于它的任意一个孩子

    Java实现:

    public class Heap<E extends Comparable> {
    	private ArrayList<E> list = new ArrayList<E>();
    
    	public Heap() {
    	}
    
    	public Heap(E[] object) {
    		for (int i = 0; i < object.length; i++) {
    			add(object[i]);
    		}
    	}
    
    	public void add(E newObject) {
    		list.add(newObject);
    		int currentIndex = list.size() - 1;
    
    		while (currentIndex > 0) {
    			int parentIndex = (currentIndex - 1) / 2;
    			if (list.get(currentIndex).compareTo(list.get(parentIndex)) > 0) {
    				E temp = list.get(currentIndex);
    				list.set(currentIndex, list.get(parentIndex));
    				list.set(parentIndex, temp);
    			} else {
    				break;
    			}
    			currentIndex = parentIndex;
    		}
    	}
    
    	public E remove() {
    		if (list.size() == 0)
    			return null;
    
    		E removedObject = list.get(0);
    		list.set(0, list.get(list.size() - 1));
    		list.remove(list.size() - 1);
    
    		int currentIndex = 0;
    		while (currentIndex < list.size()) {
    			int leftChildIndex = 2 * currentIndex + 1;
    			int rightChildIndex = 2 * currentIndex + 2;
    
    			if (leftChildIndex >= list.size())
    				break;
    			int maxIndex = leftChildIndex;
    			if (rightChildIndex < list.size()) {
    				if (list.get(maxIndex).compareTo(list.get(rightChildIndex)) < 0) {
    					maxIndex = rightChildIndex;
    				}
    			}
    
    			if (list.get(currentIndex).compareTo(list.get(maxIndex)) < 0) {
    				E temp = list.get(maxIndex);
    				list.set(maxIndex, list.get(currentIndex));
    				list.set(currentIndex, temp);
    				currentIndex = maxIndex;
    			} else
    				break;
    		}
    
    		return removedObject;
    	}
    
    	public int getSize() {
    		return list.size();
    	}
    }
    
        public static <E extends Comparable> void heapSort(E[] list) {
    		Heap<E> heap = new Heap<E>();
    
    		for (int i = 0; i < list.length; i++)
    			heap.add(list[i]);
    		for (int i = list.length - 1; i >= 0; i--) {
    			list[i] = heap.remove();
    		}
    	}
    

    7、桶排序和基数排序(时间复杂度O(dn), n为元素个数,d是所有键值中基数位置的最大值)

    一般排序算法的下限是O(nlogn)。因此,基于比较的的排序算法中没有完成得好过O(nlogn)的算法。但是,如果键值是小整数,那么可以使用桶排序,而无需比较这些键值。

    桶排序算法的工作方式如下。假设键值的范围是从0到N-1。我们需要N个标记为0,1,...,N-1的桶。如果元素的键值是i,那么就将该元素放入桶i中。每个桶中都存在和键值具有相同值的元素。可以使用ArrayList来实现一个桶。

    桶排序算法对一个线性表中元素的排序,可以描述如下:

        public void bucketSort(E[] list) {
    		E[] buckets = (E[]) new java.util.ArrayList[N];
    
    		for (int i = 0; i < list.length; i++) {
    			int key = list[i].getKey();
    
    			if (buckets[key] == null)
    				buckets[key] = new java.util.ArrayList();
    			
    				buckets[key].add(list[i]);
    		}
    
    		int k = 0;
    		for (int i = 0; i < buckets.length; i++) {
    			if (buckets[i] != null) {
    				for (int j = 0; j < buckets[i].size(); j++) {
    					list[k++] = buckets[i].get(j);
    				}
    			}
    		}
    	}
    

    基数排序的思想是将这些键值基于它们的基数位置分为小组,然后重复地从最显著的基数开始,对其应用基数排序。

      

  • 相关阅读:
    队列学哪个好
    python web 开发
    随笔
    问题集录
    大早晨地,快睡觉了,才想明白多线程代理验证是如何做的
    线程真的挺不错的,但是多了的时候也有点让人头痛
    愁死我了,写个控制台怎么好象在写解释器一样
    我越发地发现,我是在写一个解释器了
    哈哈,真有意思
    我要崩溃了。。。。
  • 原文地址:https://www.cnblogs.com/zihaowang/p/4947577.html
Copyright © 2011-2022 走看看