package com.sort;
public class Sort {
//选择排序
/*算法规则:将待排序集合(0...n)看成两部分,在起始状态中,一部分为(k..n)的待排序unsorted
* 集合,另一部分为(0...k)的已排序sorted集合,在待排序集合中挑选出最小元素并且记录下标i,
* 若该下标不等于k,那么 unsorted[i] 与 sorted[k]交换 ,一直重复这个过程,直到unsorted集
* 合中元素为空为止。
*/
public void selectSort(int[] arrays) {
for(int i=0;i<arrays.length;i++){
//记录从i到arrays.length结尾的最小值的下标
int pos = i;
for(int j=i+1;j<arrays.length;j++){
if (arrays[j]<arrays[pos]) {
pos = j;
}
}
if (i!=pos) {
int temp = arrays[i];
arrays[i] = arrays[pos];
arrays[pos] = temp;
}
}
}
//冒泡排序:相邻元素进行比较和交换
/*算法规则:由于算法每次都将一个最小的元素往上冒,我们可以将待排序集合(0...n)看成两部分,
* 一部分为(k..n)的已排序sorted集合,另一部分为(0...k)的待排序unsorted集合,每一次都在
* unsorted集合从前往后遍历,选出一个数,如果这个数比其后面的数大,则进行交换。完成一轮
* 之后,就肯定能将这一轮unsorted集合中最大的数移动到集合的最后,并且将这个数从unsorted
* 中删除,移入sorted中。
*/
public void bubbleSort(int[] arrays) {
for(int i=arrays.length-1;i>0;i--){
for(int j=0;j<i;j++){
if (arrays[j]>arrays[j+1]) {
int temp = arrays[j];
arrays[j] = arrays[j+1];
arrays[j+1] = temp;
}
}
}
}
//快速排序
//算法规则:将数组划分为大于基准数字和不大于基准数字的两组集合,然后重读操作直
//到数组中只有一个元素
private int getMiddle(int[] arrays,int lo,int hi) {
int basenum = arrays[lo];
while(lo<hi){
//从右向左找到第一个比基准数字小的数字然后跳出循环
while(lo<hi&&arrays[hi]>basenum)
hi--;
if (lo<hi) {
arrays[lo++]=arrays[hi];
}
//从左向右找到第一个比基准数字大的数字然后跳出循环
while(lo<hi&&arrays[lo]<basenum)
lo++;
if (lo<hi) {
arrays[hi--]=arrays[lo];
}
}
arrays[lo]=basenum;
return lo;
}
public void quickSort(int[] arrays,int lo,int hi) {
if (lo<hi) {
int mid = getMiddle(arrays,lo,hi);
//对左半部分进行排序
quickSort(arrays, lo, mid-1);
//对右半部分进行排序
quickSort(arrays, mid+1, hi);
}
}
//插入排序
public void insertSort(int[] arrays) {
for(int i=1;i<arrays.length;i++){
/*int j=i-1;
//在后移元素之前,需要提前保存arrays[i]的值
int temp = arrays[i];
for(;j>=0&&arrays[j]>temp;j--)
arrays[j+1]=arrays[j];*/
int j=i;
int temp = arrays[i];
for(;j>0&&arrays[j-1]>temp;j--)
arrays[j]=arrays[j-1];
arrays[j]=temp;
}
}
//希尔排序
//希尔排序是插入排序的改进,时间复杂度与步长有关,Hibbard{1, 3, ..., 2^k-1}增量的
//希尔排序的时间复杂度为O(N3/2)。
public void shellSort(int[] arrays) {
//此写法,代码不够简洁
for(int gap = arrays.length/2;gap>0;gap/=2)//步长
for(int i=0;i<gap;i++){
//每个组别都采用直接插入排序
for(int j=i+gap;j<arrays.length;j+=gap){
if (arrays[j]<arrays[j-gap]) {
int temp = arrays[j];
int k=j-gap;
//找到插入位置
while(k>=0&&arrays[k]>temp){
arrays[k+gap] = arrays[k];
k-=gap;
}
arrays[k+gap] = temp;
}
}
}
/* int len = arrays.length;
* for(int gap=len/2;gap>0;gap/=2)
for(int i=gap;i<len;i++)
for(int j=i-gap;j>=0&&arrays[j]>arrays[j+gap];j-=gap)
Swap(arrays, j, j+gap);
*/
}
//交换数组中的两个元素
private void Swap(int[] arrays,int first,int second) {
int temp = arrays[first];
arrays[first] = arrays[second];
arrays[second] = temp;
}
//堆排序
//两大问题:1、由无序序列建立一个大根堆;2、在输出堆顶元素之后重新建立一个大根堆
//堆排序对于序列的原始顺序并不敏感,但是在构建堆的过程中会花费较长的时间
public void heapSort(int[] arrays){
//由数组建立一个大根堆
int len = arrays.length;
for(int i=(len-1)/2;i>=0;i--){
AdjustHeap(arrays, i, len);
}
//输出堆顶元素,然后重新建立堆
for(int j=len-1;j>0;j--){
Swap(arrays, 0, j);
AdjustHeap(arrays, 0, j);
}
}
private void AdjustHeap(int[] arrays,int root,int length) {
int temp = arrays[root];
for(int j=root*2+1;j<length;j*=2){
//记录此节点左右孩子节点较大的下标
if (j<length-1&&arrays[j]<arrays[j+1]) {
++j;
}
if(temp>arrays[j])
break;
arrays[root]=arrays[j];
root=j;
}
arrays[root]=temp;
}
//归并排序:将待排序列分为若干个序列,每个子序列是有序的,然后将子序列合并
public void mergeSort(int[] arrays) {
getSort(arrays, 0, arrays.length-1);
}
private void getSort(int[] arrays,int left,int right) {
if (left<right) {
int center = (left + right)/2;
//对左边数组进行递归
getSort(arrays, left, center);
//对右边数组进行递归
getSort(arrays, center+1,right);
//合并
merge(arrays, left, center, right);
}
}
private void merge(int[] arrays,int left,int center,int right) {
//i为第一有序区的第一个元素
int i=left;
//j为第二有序区的第一个元素
int j=center+1;
int[] temArrays=new int[right-left+1];
//临时数组的指示下标
int k=0;
while(i<=center&&j<=right){
if (arrays[i]<=arrays[j]) {
temArrays[k++]=arrays[i++];
}else {
temArrays[k++]=arrays[j++];
}
}
//将有剩余的有序区的元素全部复制到临时数组中
while(i<=center){
temArrays[k++]=arrays[i++];
}
while(j<=right){
temArrays[k++]=arrays[j++];
}
//将排序后的数组,重新回到arrays中left到right区间
for(i=left,k=0;i<=right;i++,k++){
arrays[i]=temArrays[k];
}
}
public static void main(String[] args) {
int[] arrays = {1,-5,6,8,7,2};
new Sort().mergeSort(arrays);
for (int i = 0; i < arrays.length; i++) {
System.out.println(arrays[i]);
}
}
}
常用排序方法
最新推荐文章于 2024-11-16 05:00:00 发布