您的位置:首页 > 编程语言 > Java开发

排序算法(一):插入排序与堆排序

2017-04-24 04:11 211 查看
排序算法是算法研究中最基础的问题,本文针对排序算法,介绍几种排序算法的基本方法、时间复杂度及Java实现等内容。

原址性 :如果输入数组中仅有常数个元素需要在排序的过程中存储在数组之外,那么排序算法就是原址的。

        常用排序算法的运行时间比较



上表中,n表示要排序数据项数量。对于计数排序,数据项均在集合{0,1,...,k}内。对于基数排序,每个数据项都是d位数字的整数,每位数字可能取k个值。对于桶排序,假定关键字是半开区间[0,1)内服从均匀分布的n个实数。

一、插入排序

插入排序的思想就类似于我们玩牌,拿到手的是一把乱牌。我们从左到右排序。从第二张开始,我们与第一张比较,小的话就插到第一张前面。到后面某一张牌,我们会依次和前面的牌进行比较,直到比该牌小的位置,放到它的后面。

示例代码

public static void sortInsert(int[] n){
//int count = 0;
for(int i = 1; i < n.length; i++) {
int key = n[i];
int j = i - 1;
while(j >= 0 && n[j] > key){
n[j+1] = n[j];
j--;
}
n[j+1] = key;
System.out.print(i + ":");
for(int num: n)
System.out.print(num + " ");
System.out.println();
}
}


生成一个随机数组并进行插入排序,运行结果如下:

运行结果

E:\code\jv\alg0rithmOjava\排序>java InsertSort
35 58 24 75 77 17 73 64 66 88
1:35 58 24 75 77 17 73 64 66 88
2:24 35 58 75 77 17 73 64 66 88
3:24 35 58 75 77 17 73 64 66 88
4:24 35 58 75 77 17 73 64 66 88
5:17 24 35 58 75 77 73 64 66 88
6:17 24 35 58 73 75 77 64 66 88
7:17 24 35 58 64 73 75 77 66 88
8:17 24 35 58 64 66 73 75 77 88
9:17 24 35 58 64 66 73 75 77 88
17 24 35 58 64 66 73 75 77 88


二、堆排序

堆排序通过“堆”数据结构进行排序,其时间复杂度是O(nlgn),并具有空间原址性。结合了插入排序和归并排序的优点。

1. 堆

(二叉)堆是一个数组,可以近似的看成一个完全二叉树,树上的每一个节点对应数组中的一个元素。堆heap的数组Array包括两个属性,一个是数组的长度A.length,一个是堆的大小heap.size,并有 0 <= heap.size <= A.length。也就是说,数组中的数据不一定都是堆的有效数据。

最大堆 : 二叉堆又可以分为两种形式:最大堆和最小堆。最大堆的父节点的数据要比子节点的都大,最小堆则是都要小。堆排序算法中用的是最大堆,构造优先队列一般用最小堆。

堆的高度 : 一个堆节点的高度就是某节点到叶节点最长的简单路径的边数。而堆的高度则对应根节点的高度。就是O(lgn).

2. 建堆



通过该示例,我们可以看出,对左右子树都是最大堆的根节点维护最大堆的方法。

所以将一个普通的堆维护成最大堆的方法,就是从底到根依次维护一次。不过不难发现,最底层的节点是没有子节点的,自然满足最大堆。也就是应该从开始有子节点的节点处开始倒序遍历维护节点。根据完全二叉树的性质,这个节点就是 heap.size / 2.

实现代码

public void builtMaxHeapify(){

for(int i = heapSize/2; i >= 0; i--) {
MaxHeapify(i);
}
}

public void exchange(int i, int j) {
heapArray[i] = heapArray[i] + heapArray[j];
heapArray[j] = heapArray[i] - heapArray[j];
heapArray[i] = heapArray[i] - heapArray[j];
}

public void MaxHeapify(int i) {
int largest = i;
int l = (i + 1) << 1;
int r = l + 1;
if( l <= heapSize && heapArray[l-1] > heapArray[i])
largest = l-1;
else
largest = i;
if( r <= heapSize && heapArray[r -1] > heapArray[largest])
largest = r-1;
if(largest != i){
heapArray[i] = heapArray[i] + heapArray[largest];
heapArray[largest] = heapArray[i] - heapArray[largest];
heapArray[i] = heapArray[i] - heapArray[largest];
MaxHeapify(largest);
}
}
}


运行结果

>java Test
18 26 66 75 1 53 47 80 47 71
80 75 66 47 71 53 47 26 18 1
1 75 66 47 71 53 47 26 18 80
75 71 66 47 1 53 47 26 18
18 71 66 47 1 53 47 26 75
71 47 66 26 1 53 47 18
18 47 66 26 1 53 47 71
66 47 53 26 1 18 47
47 47 53 26 1 18 66
53 47 47 26 1 18
18 47 47 26 1 53
47 26 47 18 1
1 26 47 18 47
47 26 1 18
18 26 1 47
26 18 1
1 18 26
18 1
1 18
1
1 18 26 47 47 53 66 71 75 80
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐