整数排序
来源:互联网 发布:linux如何创建文件夹 编辑:程序博客网 时间:2024/05/23 14:34
给一组整数,按照升序排序。使用归并排序,快速排序,堆排序或者任何其他 O(n log n) 的排序算法。
若从空间复杂度来考虑:首选堆排序,其次是快速排序,最后是归并排序。
若从稳定性来考虑,应选取归并排序,因为堆排序和快速排序都是不稳定的。
若从平均情况下的排序速度考虑,应该选择快速排序。
1.归并排序:分治法(Divide and Conquer)的一个非常典型的应用
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
算法思想:将待排序序列A[0...n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并,得到n/2个长度为2的有序表;将这些有序序列再次归并,得到n/4个长度为4的有序序列......如此反复进行下去,直到最后得到一个长度为n的有序序列。
public class Sort {
/**
* @param A an integer array
* @return void
*/
public void sortIntegers2(int[] A) {
// Write your code here
for (int size = 1; size < A.length; size = 2 * size) {
MergeSort(A, size, A.length);
}
}
/*.................归并排序.......................*/
//合并
public void Merge(int[] array,int low, int mid, int high) {
int i = low; // i是第一段序列的下标
int j = mid + 1; // j是第二段序列的下标
int k = 0; // k是临时存放合并序列的下标
int[] array2 = new int[high - low + 1]; // array2是临时合并序列
// 扫描第一段和第二段序列,直到有一个扫描结束
while (i <= mid && j <= high) {
// 判断第一段和第二段取出的数哪个更小,将其存入合并序列,并继续向下扫描
if (array[i] <= array[j]) {
array2[k] = array[i];
i++;
k++;
} else {
array2[k] = array[j];
j++;
k++;
}
}
// 若第一段序列还没扫描完,将其全部复制到合并序列
while (i <= mid) {
array2[k] = array[i];
i++;
k++;
}
// 若第二段序列还没扫描完,将其全部复制到合并序列
while (j <= high) {
array2[k] = array[j];
j++;
k++;
}
// 将合并序列复制到原始序列中
for (k = 0, i = low; i <= high; i++, k++) {
array[i] = array2[k];
}
}
//分解 size为子表长度,length为数组长度
public void MergeSort(int[] array, int size, int length) {
int i = 0;
// 归并长度为size的两个相邻子表
for (i = 0; i + 2 * size - 1 < length; i = i + 2 * size) {
Merge(array, i, i + size - 1, i + 2 * size - 1);
}
// 当最后余下两个子表,后者长度小于size
if (i + size - 1 < length) {
Merge(array, i, i + size - 1, length - 1);
}
for(int k =0;k<length;k++)
System.out.print(array[k]+" ");
System.out.println(" ");
}
}
2.快速排序:对冒泡排序的一种改进
它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。不稳定,较复杂。
public int division(int[] list, int low, int high) {
// 以最左边的数为基准
int standard = list[low];
while (low < high) {
// 从序列右端开始,向左遍历,直到找到小于基准的数
while (low < high && list[high] >= standard)
high--;
// 找到了比standard小的元素,将这个元素放到最左边的位置
list[low] = list[high];
// 从序列左端开始,向右遍历,直到找到大于standard的数
while (low < high && list[low] <= standard)
low++;
// 找到了比standard大的元素,将这个元素放到最右边的位置
list[high] = list[low];
}
// 最后将standard放到low位置。此时,low位置的左侧数值应该都比low小,右侧数值应该都比low大。
list[low] = standard;
return low;
}
private void quickSort(int[] list, int low, int high) {
// 左下标一定小于右下标,否则就越界了
if (low < high) {
// 对数组进行分割,取出下次分割的基准标号
int standard = division(list, low, high);
System.out.format("low = %d high = %d:\t", low,high);
System.out.format("standand = %d:\t", list[standard]);
for(int i =0;i<list.length;i++)
System.out.print(list[i]+" ");
System.out.println("");
// 对“基准标号“左侧的一组数值进行递归的切割,以至于将这些数值完整的排序
quickSort(list, low, standard - 1);
// 对“基准标号“右侧的一组数值进行递归的切割
quickSort(list, standard + 1, high);
}
}
3.堆排序:利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种
堆是一棵顺序存储的完全二叉树。
(1) Ri <= R2i+1 且 Ri <= R2i+2 (小根堆)
(2) Ri >= R2i+1 且 Ri >= R2i+2 (大根堆)
其中i=1,2,…,n/2向下取整;
public class Solution {/**
* @param A an integer array
* @return void
*/
public void sortIntegers2(int[] A) {
if (A == null || A.length <= 1) { //要先判断,不然后面会报数组越界的错误
return;
}
heapSort(A);
}
public void HeapAdjust(int[] array, int parent, int length) {//parent为当前节点,length为数组长度
int temp = array[parent]; // temp保存当前父节点
int child = 2 * parent + 1; // 先获得左孩子
while (child < length) {
// 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点
if (child + 1 < length && array[child] < array[child + 1]) {
child++;
}
// 如果父结点的值已经大于孩子结点的值,则直接结束
if (temp >= array[child])
break;
// 把孩子结点的值赋给父结点
array[parent] = array[child];
// 选取孩子结点的左孩子结点,继续向下筛选,!!!!相当于递归函数很重要,要确保左右子树的大小保证
parent = child;
child = 2 * child + 1;
}
array[parent] = temp;
}
public void heapSort(int[] list) {
// 循环建立初始堆
for (int i = list.length / 2; i >= 0; i--) {//length/2是可能存在的最大父节点
HeapAdjust(list, i, list.length);
}
// 进行n-1次循环,完成排序
for (int i = list.length - 1; i > 0; i--) {
// 最后一个元素和第一元素进行交换
int temp = list[i];
list[i] = list[0];
list[0] = temp;
// 筛选 R[0] 结点,得到i-1个结点的堆
HeapAdjust(list, 0, i);
}
}
}
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- 整数排序
- iOS app上架流程
- 调出系统的拨号键盘,并且将号码显示在拨号键盘上
- linux网络编程之TCP/IP基础(一):TCP/IP协议栈与数据报封装
- 干货:Java几种线程池的分析和使用。
- 避免在Java接口中使用数组的3个理由
- 整数排序
- 永远要设定Deadline(最后期限),完成比完美更重要
- 程序员笑话系列(1)
- android 自定义带动画的统计饼图
- canvas-基础
- CentOS通过删除旧内核解决/boot空间不足的问题
- Android APK反编译教程
- MySQL中索引的创建与使用
- 扩展ElasticSearch:实现分片并可用于存储亿万文档的实践