选择排序
算法中最基础的当数排序了,今天整理记录一下Java中的选择排序。
这里的排序方式按从小到大讲,由大到小其实就是改变下符号。
选择排序有两种实现方式:
一、简单的选择排序
二、堆排序
因为简单的选择排序比较简单,所以这里先讲它吧。
一、简单的选择排序
简单的选择排序,思想很简单;
①开始找到序列1…. n 中最小的元素,把它和 1 处进行交换;
②然后找到2 …… n 中最小的元素,把它和 2 处进行交换;
③以此类推,可知需要遍历 n - 1 次元素。
代码实现
public void selectSort(int[] elements){
int length = elements.length;
for (int i = 0; i < length - 1 ; i++) { // 利用外层循环控制序列开始的位置
/*下面就是找到序列 i ...... length 中最小元素的下标*/
int minIndex = i;
for (int j = i + 1; j < length; j++) {
if (elements[j] < elements[minIndex]){
minIndex = j;
}
}
/*下面是交换位置*/
if (minIndex != i){
int temp = elements[minIndex];
elements[minIndex] = elements[i];
elements[i] = temp;
}
}
}
二、堆排序
堆排序,堆排序相对就是很复杂了,它涉及到了完全二叉树和有顺序的完成二叉树,也是因为复杂,这种排序方式相当的快,关于各种排序方式的转到博客
Java排序 —— 归并排序 及 排序算法比较图。 这里先跟大家简单说说完全二叉树和有顺序的完全二叉树
完全二叉树:一种树形结构,节点分为父节点和左、右孩子节点;且从倒数第二层开始以上各层的每个节点都有两个孩子节点,其余节点随意。
有顺序的完全二叉树:一种按大顶堆/小顶堆 排列的完全二叉树。
按小顶堆排序的完全二叉树:父节点必须比子节点小;
按大顶堆排序的完全二叉树:父节点必须比子节点大。
因为我们要实现从小到到大排序,所以这里采用按大顶堆排序;
堆排序的基本思想就是:
1、就序列 [1…..n] 看成是完全二叉树的结构;
2、对完全二叉树按大顶堆进行排序;
3、将排序后的序列的头尾交换数据;
4、然后把 [1…..n-1] 的序列继续看出完全二叉树结构,重新进行大顶堆排序;
5、重复以上过程 n -1 次。
这里有个隐含的条件就是:
数组对应的完全二叉树有这么个关系
父节点:i
左节点:2 * i + 1
右节点:2 * i + 2 //隐含 有右节点就一定有左节点
//由以上关系可以知道,数组从第0个到第length / 2 - 1 个元素才是父节点。
代码实现
private void heapSort(int[] elements) {
int length = elements.length;
for (int i = length; i >= 1; i--) {//长度由于数组头尾元素的交换而递减
maxHeap(elements, i, 0);//从第一个元素开始排序完全二叉树,实现有顺序的完全二叉树
swap(elements, 0, i - 1); // 交换数组第一个元素和最后一个元素
}
}
// 对父节点和左、右节点进行排序,实现有顺序的完全二叉树
private void maxHeap(int[] elements, int heapSize, int index) {
int largest = index; // 完全二叉树中某个父节点
int left = index * 2 + 1; // 某个父节点的左节点
int right = index * 2 + 2; // 某个父节点的右节点
//将父节点的值和 比父节点值大的孩子节点的值交换。
if (left < heapSize/*判读有左节点吗*/ && elements[left] > elements[index])
largest = left;
if (right < heapSize /*判读有右节点吗*/&& elements[right] > elements[largest])
largest = right;
if (index != largest){
swap(elements, index, largest);
}
if (index <= elements.length / 2 - 1){ // 还是父节点吗
maxHeap(elements, heapSize, index + 1);//对下一个父节点排序
}
}
private void swap(int[] elements, int left, int right){
int temp = elements[left];
elements[left] = elements[right];
elements[right] = temp;
}