算法(2)

上一篇是交换排序

那么这一篇就是排序的第二种,选择排序:

什么是选择排序呢?让我们来看个例子:

 20,90,100,69,9,3.

选择排序:从基准第一位开始,从二十开始遍历,第一遍,选出最小的3,跟20交换 3,90,100,69,9,20

依次类推:3,9,100,69,90,20

     3,9,20,69,90,100

恰好排序完成,这个就是选择排序。

下面我们来看看java算法实现他的时间:

  1. // 选择排序
  2.      private static void sel_sort(int[] a) {
  3.           //首先从第一个开始遍历选择一个最小的
  4.           for (int i = 0; i < a.length-1; i++) {
  5.                int min=i;
  6.                for (int j = i+1; j < a.length; j++) {
  7.                     if (a[j]<a[min]) {
  8.                          min=j;
  9.                     }
  10.                }
  11.                int temp=a[min];
  12.                a[min]=a[i];
  13.                a[i]=temp;
  14.           }
  15.           System.out.println(Arrays.toString(a));
  16.      }

时间仍然是很可怕的:291ms

 

 

 

那么现在我们来了解一下另一种选择排序堆排序:

由堆排序就引出一种数据结构二叉树,而堆排序用的也叫二叉堆,二叉堆分最大堆和最小堆

堆:堆是一种时间复杂度为O(nlogn)的排序算法,同时和插入算法一样,就地排序,不需要额外的空间。堆排序需要用到一种被成为最大堆的数据结构,可以看成是一颗完全二叉树,树里面除了最后一层剩下的全是填满的。因此,树里面的每个节点的子女和双亲节点的序号都可以由当前算出。

P(i)=i/2  取整  legt(i)=2*i  right(i)=2*i+1;
上面就是一个最大堆。父节点的值大于子节点的值。这个特点可以使他实现nlogn的排序
 
首先构建最大堆,然后在最大堆中把根和最后一个交换,构建。
import java.util.Arrays;

public class HeapSorter {
     public static void heapSort(int[] a) {
          bulidHeap(a);
          int n=a.length;
          int i=0;
          for(i=n-1;i>=1;i--){
               swap(a, 0, i);
               heapify(a, 0, i);
          }
     }

     // 构建堆
     private static void bulidHeap(int[] a) {
          int n = a.length;// 数组元素的个数
          for (int i = n / 2 - 1; i >= 0; i--) {// 因为堆的性质,(n/2+1)~n的元素都是叶子节点
               heapify(a, i, n);
          }
     }

     private static void heapify(int[] a, int i, int n) {
          int left = 2 * i + 1;// 左孩子的下标
          int right = 2 * i + 2;// 右孩子的下标
          int largest = 0;// 寻找三个节点中最大值节点的下标
          if (left < n && a[left] > a[i]) {
               largest = left;
          } else if (right < n && a[right] > a[i]) {
               largest = right;
          } else {
               largest = i;
          }
          if (largest != i) {
               swap(a, largest, i);
               heapify(a, largest, n);
          }
     }

     // 交换功能
     private static void swap(int[] a, int largest, int i) {
          int temp;
          temp = a[largest];
          a[largest] = a[i];
          a[i] = temp;
     }
     
     public static void main(String[] args) {
          // 原始数据
          int a[] = new int[10000];
          for (int i = 0; i < 10000; i++) {
               a[i] = (int) (Math.random() * 10000);
          }
          // 排序
          System.out.println(Arrays.toString(a));
          long starTime = System.currentTimeMillis();
          heapSort(a);
          System.out.println(Arrays.toString(a));
          long endTime = System.currentTimeMillis();
          System.out.println(endTime - starTime);
     }
}
 
 
 
输出结果时间:32ms比快速排序的效率看起来还要慢一点。
posted @ 2015-06-16 22:27  呜呜啦啦拉  阅读(144)  评论(0)    收藏  举报