package algorithm;
import java.util.Collections;
import java.util.Vector;
public class Sort {
//冒泡排序
public void BubbleSort(int[] a){
boolean flag = true;
for (int i = 0; i < a.length; i++) {
flag = false;//用于判断上次排序是否执行交换
for (int j = 1; j < a.length-i; j++) {
if(a[i] > a[j]){//执行交换
int temp = a[j];
a[j]=a[i];
a[i]=temp;
flag=true;
}
}
if(!flag){
break;
}
}
}
//选择排序
public void SelectSort(int[] a){
for (int i = 0; i < a.length; i++) {
int minIndex = i;//每次循环初始化最小值所在位置
for (int j = i+1; j < a.length; j++) {
if(a[minIndex]>a[j]){
minIndex = j;
}
}
if(minIndex != i){//判断是否有更小的数
int temp = a[i];
a[i]=a[minIndex];
a[minIndex]=a[i];
}
}
}
//插入排序
public void InsertionSort(int[] a){
for (int i = 1; i < a.length; i++) {
int key = a[i];
int j;
for (j = i-1; j >= 0 && a[j] > key; j--) {
a[j+1] = a[j];
}
a[j] = key;
}
}
//归并排序
public void Merge(int[] a,int start,int mid,int end){//思想大致是,把数据分成左右两组,两组均为有序数组,然后再将其合并
int leftIndex = start;
int rightIndex = mid + 1;
int[] temp = new int[end-start+1];//把排好的数据放到temp数组中
int tempIndex = 0;
while (leftIndex <= mid && rightIndex <= end) {
if (a[leftIndex] <= a[rightIndex]) {
temp[tempIndex++] = a[leftIndex++];
}
else {
temp[tempIndex++] = a[rightIndex++];
}
}
while (leftIndex <= mid) {
temp[tempIndex++] = a[leftIndex++];
}
while (rightIndex <= end) {
temp[tempIndex++] = a[rightIndex++];
}
for (int i = start; i <= end; i++) {//把temp中的排好的值传给原数组
a[i] = temp[i - start];
}
}
public void MergeSort(int[] a, int start, int end) {
if (start >= end) {//当数组只有一个值时退出
return;
}
int mid = (start + end) / 2;
MergeSort(a, start, mid);//递归左边
MergeSort(a, mid + 1, end);//递归右边
Merge(a, start, mid, end);
}
//快速排序
public void QuickSort(int[] a,int left,int right){
int i=left;
int j=right;
int pivot = a[left];//定义一个基准
while(i<j){//确保基准左边的数小于它,右边的数都大于它
while(i<j&&a[j]>=pivot) {//注意是大于等于,没有等于可能会陷入死循环
j--;
}
a[i]=a[j];
while(i<j&&a[i]<=pivot){
i++;
}
a[j]=a[i];
}
a[i]=pivot;
if(i-left-1>0){//如果基准左边超过1个数,递归快排
QuickSort(a,left,i-1);
}
if(right-i-1>0){//如果基准右边超过1个数,递归快排
QuickSort(a,i+1,right);
}
}
//堆排序
public void Heap(int[] a, int len, int index){//构建一个大根堆,len是a数组的长度,index是第一个非子节点的下标
int left = 2*index + 1; // index的左子节点
int right = 2*index + 2;// index的右子节点
int maxIdx = index;
if(left<len && a[left] > a[maxIdx]) maxIdx = left;
if(right<len && a[right] > a[maxIdx]) maxIdx = right;
if(maxIdx != index)
{
int temp = a[maxIdx];
a[maxIdx] = a[index];
a[index] = temp;
Heap(a, len, maxIdx);
}
}
public void HeapSort(int[] a,int size){//size是a数组的长度
for (int i = size/2-1; i >=0; i--) {//构建大根堆从最后一个非叶子结点向上
Heap(a,size,i);
}
for(int i = size - 1; i >= 1; i--)
{
// 将当前最大的放置到数组末尾
int temp = a[0];
a[0] = a[i];
a[i] = temp;
Heap(a, i, 0); //将未完成排序的部分继续进行堆排序,这里令len等于i,确保最大位不再参与排序
}
}
//希尔排序
public void ShellSort(int[] a){
int size = a.length;//数组长度
for (int increment = size/2; increment > 0 ; increment/=2) {//分组思想的应用
for (int i = increment; i < size; i++) {
int temp = a[i];
int j;
for (j = i; j >= increment; j -= increment) {
if (temp < a[j - increment]) {
a[j] = a[j - increment];
}
else {
break;
}
}
a[j] = temp;
}
}
}
//计数排序
void CountSort(int[] a, int max, int min) {//max为数组中的最大值,min为数组中的最小值
int[] count = new int[max - min + 1];
for (int i = 0; i < a.length; i++) {
int num = a[i];
count[num - min]++;
}
int index = 0;
for (int i = 0; i <count.length; i++) {
while (count[i] != 0) {
a[index++] = i + min;
count[i]--;
}
}
}
//桶排序
public void BucketSort(Vector<Integer> a) {
int min = a.get(0);
int max = a.get(0);
for (int i = 1; i < a.size(); i++) {//确定最大值和最小值
if (a.get(i) > max) {
max = a.get(i);
}
if (a.get(i) < min) {
min = a.get(i);
}
}
int bucketNum = (max - min) / a.size() + 1;//桶数
Vector<Vector<Integer>> bucketArr = new Vector<>(bucketNum);
//入桶
for (int i = 0; i < a.size(); i++) {
int num = (a.get(i) - min) / a.size();
bucketArr.get(num).add(a.get(i));
}
//每个桶内部排序
int index = 0;
for (int i = 0; i < bucketArr.size(); i++) {
Collections.sort(bucketArr.get(i));
for (int j = 0; j < bucketArr.get(i).size(); j++) {
a.setElementAt(bucketArr.get(i).get(j),index++);
}
}
}
//找到最大值
int computeMax(Vector<Integer> arr) {
int ma = arr.get(0);
for (int i = 1; i < arr.size(); i++) {
if (arr.get(i) > ma) {
ma = arr.get(i);
}
}
return ma;
}
//最长的位数
int getDistance(Vector<Integer> arr) {
int ma = computeMax(arr);
int digits = 0;
while (ma != 0) {
digits++;
ma = ma / 10;
}
return digits;
}
//基数排序
void radixSort(Vector<Integer> arr) {
Vector<Vector<Integer>> buckets = new Vector<>(10,arr.size());
int distance = getDistance(arr);
int temp = 1;
int round = 1;//控制键值排序依据在哪一位
while (round <= distance) {
// 用来计数:数组counter[i]用来表示该位是i的数的个数
Vector<Integer> counter = new Vector<>(10,0);
// 将array中元素分布填充到bucket中,并进行计数
for (int i = 0; i < arr.size(); i++) {
int which = (arr.get(i) / temp) % 10;
buckets.get(which).setElementAt(arr.get(i),counter.get(which));
counter.setElementAt(counter.get(which)+1,counter.get(which));
}
int index = 0;
// 根据bucket中收集到的arr中的元素,根据统计计数,在arr中重新排列
for (int i = 0; i < 10; i++) {
if (counter.get(i) != 0) {
for (int j = 0; j < counter.get(i); j++) {
arr.setElementAt(buckets.get(i).get(j),index++);
}
}
counter.setElementAt(0,i);
}
temp *= 10;
round++;
}
}
}