import java.util.*;
public class Sort {
public static void main(String[] args) {
Sort s = new Sort();
int[] array = new int[]{1, 6, 2, 7, 3, 9, 10};
// int[] array=new int[]{6,3};
s.countSort(array);
for (int i : array)
System.out.print(i + " ");
}
/**
* 冒泡排序
* 从头到尾,比较大小,大的向后放
* 时间复杂度O(n^2)
* 空间复杂度O(1)
*/
public void bubbleSort(int[] array) {
int temp;
for (int i = 1; i < array.length; i++) {
for (int j = 0; j < array.length - i; j++) {
if (array[j] > array[j + 1]) {
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
}
/**
* 选择排序
* 每次从数组中找出最大值,将其与最后一个元素交换
* 时间复杂度O(n^2)
* 空间复杂度O(1)
*/
int max, temp;
public void selectSort(int[] array) {
for (int i = array.length - 1; i > 0; i--) {
//在剩余元素中寻找最大值
max = 0;
for (int j = 0; j <= i; j++) {
if (array[j] > array[max]) {
max = j;
}
}
//最大值放到最后
temp = array[i];
array[i] = array[max];
array[max] = temp;
}
}
/**
* 插入排序
* 从数组中取出一个元素,查找其在新数组中的位置,进行插入
* 有序数组从后向前查
* 时间复杂度O(n^2)
* 空间复杂度O(1)
*/
public void insertSort(int[] array) {
int temp;
for (int i = 1; i < array.length; i++) {
//缓存当前待插入值
temp = array[i];
//从后向前
int j = i - 1;
for (; j >= 0; j--) {
//找到待插入位置
if (temp > array[j]) {
array[j + 1] = temp;
break;
}
//数组元素后移
array[j + 1] = array[j];
}
if(j==-1) {
array[0] = temp;
}
}
}
/**
* 快速排序
* 一趟排序将数组分为两部分,一部分的数据大于另一部分的数组,在递归进行快速排序
*/
public void quickSort(int[] array) {
quickSort(array, 0, array.length - 1);
}
public void quickSort(int[] array, int start, int end) {
//确定一个分割点
int mid = array[start];
int left = start;
int right = end;
while (left < right) {
//必须先右后左,若先左,则左永远不会+1
//从右向左找一个小于mid的值
while (array[right] > mid && left < right) right--;
array[left] = array[right];
//从左向右找一个大于mid的值
while (array[left] < mid && left < right) left++;
array[right] = array[left];
}
array[left] = mid;
//递归,分别对两侧进行快速排序
if (left - 1 > start) quickSort(array, start, left - 1);
if (right + 1 < end) quickSort(array, right + 1, end);
}
/**
* 堆排序
* 构建大顶堆,将最后一个元素与堆顶交换,再构建大顶堆,以此类推,直到最后一个元素
* 堆是完全二叉树,一个数组的下标为i,则他的父节点是(i-1)/2
*/
public void heapSort(int[] array) {
int temp;
for (int i = array.length - 1; i > 0; i--) {
buildBigHeap(array, 0, i);
//将栈顶与最后一个元素交换
temp = array[0];
array[0] = array[i];
array[i] = temp;
}
}
public void buildBigHeap(int[] array, int start, int end) {
int temp;
for (int i = end; i > start; i--) {
if (array[i] > array[(i - 1) / 2]) {
temp = array[i];
array[i] = array[(i - 1) / 2];
array[(i - 1) / 2] = temp;
}
}
}
/**
* 归并排序(2路归并)
* 将一个数组对半拆分,直到数据两两一组,之后合并排序,这样将两个有序数组合并为一个有序数组,直到最后一个结果
*/
public void mergeSort(int[] array) {
int[] result = new int[array.length];
split(array, 0, array.length - 1);
}
public void split(int[] array, int start, int end) {
if (start < end) {
int mid = (end + start) / 2;
split(array, start, mid);
split(array, mid + 1, end);
merge(array, start, mid, end);
}
}
public void merge(int[] array, int start, int mid, int end) {
int left = start;
int right = mid + 1;
int cur = 0;
int[] result = new int[end - start + 1];
while (left <= mid && right <= end) {
if (array[left] < array[right]) {
result[cur++] = array[left++];
} else {
result[cur++] = array[right++];
}
}
while (left <= mid) {
result[cur++] = array[left++];
}
while (right <= end) {
result[cur++] = array[right++];
}
System.arraycopy(result, 0, array, start, end - start + 1);
}
/**
* 基数排序
* 所有数字按照个十百千,分别进行排序,最后一次排序的结果就是有序的
* 1.找出最大值
* 2.所有数字的位数与最大值补齐
* 3.从个位开始排序
*/
public void radixSort(int[] array) {
int max = array[0];
//找出最大值
for (int i = 0; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
//判断最大值有多少位
int maxLength = 1;
while (max >= 10) {
maxLength *= 10;
max = max / 10;
}
//每一位单独排序
for (int i = 1; i <= maxLength; i *= 10) {
radixSort(array, i);
}
}
public void radixSort(int[] array, int place) {
//因为一位数只有0-9共10种情况,因此创建一个数组,每个数组存储一个链表
List<LinkedList> list = new ArrayList();
for (int i = 0; i < 10; i++) {
list.add(new LinkedList<Integer>());
}
//将节点插入相应位置
for (int i = 0; i < array.length; i++) {
list.get((array[i] / place) % 10).add(array[i]);
}
//将列表元素放进数组中
Iterator iterator = list.iterator();
LinkedList linkedList;
int cur = 0;
while (iterator.hasNext() && cur < array.length) {
linkedList = (LinkedList) iterator.next();
while (!linkedList.isEmpty()) {
array[cur++] = (int) linkedList.getFirst();
linkedList.remove();
}
}
}
/**
* 希尔排序
* 设置步长,相差步长的元素分为一组,进行快速排序
* 缩小步长为原来的一半,重复上步
* 当步长为1时,即全部数据有序
*/
public void shellSort(int[] array) {
//设置步长为 数组长度的一半,之后不断折半
for (int step = (array.length+1)/ 2; step > 0; step = (step+1)/2) {
for (int i = 0; i < step; i++) {
shellSort(array, i, step);
}
if(step==1)
break;
}
}
public void shellSort(int[] array, int start, int step) {
int temp;
//第一个已经有序
for (int i = start+step; i < array.length - 1; i += step) {
temp = array[i];
//从有序表中查找
int j = i-step;
for (; j >= start; j -= step) {
if (temp > array[j]) {
array[j+step]=temp;
break;
}
array[j+step]=array[j];
}
if(j==start-step){
array[start]=temp;
}
}
}
/**
* 桶排序
* 1.确定桶的数量,通过(max-min)/len+1
* 2.用arraylist存储桶,桶内存储arraylist
* 3.将数组元素分到桶内
* 4.对每个桶分别排序
* 5.遍历所有桶,输出结果
*/
public void bucketSort(int[] array) {
//找出最大最小值
int min=array[0];
int max=array[0];
for(int i=1;i<array.length;i++){
min=min<array[i]?min:array[i];
max=max>array[i]?max:array[i];
}
//确定桶的数量,+1是避免max-min<len
int bucket=(max-min)/array.length+1;
//创建桶
List<ArrayList<Integer>> list=new ArrayList<>(bucket);
for(int i=0;i<bucket;i++){
list.add(new ArrayList<Integer>());
}
//元素入桶
for(int i=0;i<array.length;i++){
list.get((array[i]-min)/array.length).add(array[i]);
}
//对桶排序
for(int i=0;i<list.size();i++){
Collections.sort(list.get(i));
}
//将桶中元素取出,放入数组
int cur=0;
Iterator<ArrayList<Integer>> iterator = list.iterator();
while(iterator.hasNext()){
Iterator<Integer> iterator1 = iterator.next().iterator();
while(iterator1.hasNext()){
array[cur++]=iterator1.next();
}
}
}
/**
* 计数排序
* 将数组内数组映射到数组下标,数组元素大小代表出现的次数
* 1.求出数组长度,max-min+1
* 2.偏移量为min
* 3.将元素对应的数组元素+1
* 4.按照数组元素大小输出数组元素
*/
public void countSort(int[] array) {
int min=array[0];
int max=array[0];
for(int i=1;i<array.length;i++){
min=min<array[i]?min:array[i];
max=max<array[i]?array[i]:max;
}
int[] newArray=new int[max-min+1];
//将数组元素映射到新数组上
for(int i=0;i<array.length;i++){
newArray[array[i]-min]++;
}
int cur=0;
for(int i=0;i<newArray.length;i++){
while(newArray[i]--!=0){
array[cur++]=i+min;
}
}
}
}