/**
* 冒泡排序(不稳定)
* 时间复杂度:o(n^2)
* 空间复杂度:O(1)
* @author 98602
*
*/
public class BubbleSort {
public int[] bubbleSort(int[] A, int n) {
int temp;
for(int i=n-1;i>0;i--){
for(int j = 0;j<i;j++){
if(A[j]>A[j+1]){
temp = A[j];
A[j] = A[j+1];
A[j+1] = temp;
}
}
}
return A;
}
}
/**
* 选择排序
* 时间复杂度:O(n^2)
* 空间复杂度:O(1)
* @author 98602
*
*/
public class SelectedSort {
public int[] selectionSort(int[] A, int n) {
int index = 0;
for (int i = 0; i < n; i++) {
index = i;
for (int j = i + 1; j < n; j++) {
if (A[j] < A[index]) {
index = j;
}
}
if (index != i) {
int temp = A[i];
A[i] = A[index];
A[index] = temp;
}
}
return A;
}
}
/**
* 插入排序
* 时间复杂度:O(n^2)
* 空间复杂度:O(1)
* @author 98602
*
*/
public class InsertSort {
public int[] insertionSort(int[] A, int n) {
int i, j, temp;
for(i = 1; i < n; i++){
temp = A[i];
for(j = i; j > 0 && A[j - 1] > temp; j-- ){
A[j] = A[j - 1];//先将前面的数后移
}
A[j] = temp;//最后再插入
}
return A;
}
}
/**
* 快速排序(不稳定)
* 时间复杂度:O(N*logN)
* 空间复杂度:O(logN)~O(N)
* @author 98602
*
*/
public class QuickSort {
public int[] quickSort(int[] A, int n) {
quick_sort(A,0,n-1);
return A;
}
private void quick_sort(int[] a, int start, int end) {
if(start<end){
int temp = a[end];//取最后一个值为中间值
int index = start;//左边区间的即将插入的位置
for(int i = start;i<end;i++){
if(a[i] < temp){//比中间值小,放到左边区间
swap(a,i,index);
index++;//跟新即将插入的位置
}
}
swap(a,index,end);//将中间值放入左边区间
quick_sort(a, index+1, end);//递归左边区间
quick_sort(a, start, index-1);//递归右边区间
}
}
private void swap(int[] a, int i, int index) {
if(i!=index){
int temp = a[i];
a[i] = a[index];
a[index] = temp;
}
}
}
/**
* 归并排序
* 时间复杂度:o(N*logN)
* 空间复杂度:O(N)
* @author 98602
*
*/
public class MergeSort {
public static void main(String[] args) {
MergeSort ms = new MergeSort();
ms.mergeSort(new int[]{1,2,3,5,2,3},6);
}
public int[] mergeSort(int[] A, int n) {
merge_sort(A, 0, n - 1);
return A;
}
private void merge_sort(int[] a, int left, int right) {
// for(int i = left;i<=right;i++){
// System.out.print(a[i] + " ");
// }
// System.out.println();
if (left < right) {
int mid = (left + right) >> 1;//取中间值
merge_sort(a, left, mid);//左递归
merge_sort(a, mid + 1, right);//右递归
merge(a, left, mid, right);//左右合并
}
}
private void merge(int[] a, int left, int mid, int right) {
int i = left,//指向左数组的开始位置
j = mid+1,//指向右数组的开始位置
k = 0;//即将放入temp数组的位置
int[] temp = new int[right-left+1];//缓存数组
while(i<=mid&&j<=right){//将两个数组中小的放入temp数组
if(a[i]<a[j]){
temp[k++] = a[i++];
}else{
temp[k++] = a[j++];
}
}
while(i<=mid){//如果左边数组没遍历完,则继续遍历将剩下的放入temp数组中
temp[k++] = a[i++];
}
while(j<=right){//如果右边数组没遍历完,则继续遍历将剩下的放入temp数组中
temp[k++] = a[j++];
}
for(i = 0;i<k;i++){
a[left+i] = temp[i];//将缓存数组赋给原始数组
}
}
}
/**
* 堆排序(不稳定)
* 时间复杂度:O(N*logN)
* 空间复杂度:O(1)
* @author 98602
*
*/
public class HeapSort {
public static void main(String[] args) {
HeapSort hs = new HeapSort();
int[] a = new int[]{10,15,56,25,30,70};
hs.heapSort(a,6);
for(int i=0;i<a.length;i++){
System.out.print(a[i] + " ");
}
}
public int[] heapSort(int[] A, int n) {
// write code here
//1,建立大根堆
A=buildMaxHap(A);
//2,调整排序
for(int i=n-1;i>0;i--){
//堆顶和堆底元素交换
int tem=A[0];
A[0]=A[i];
A[i]=tem;
adjustHeap(A, 0, i);//将剩余的元素整理成堆
}
return A;
}
private static int[] buildMaxHap(int[] A) {
for(int i=A.length/2;i>=0;i--){
adjustHeap(A,i,A.length);
}
return A;
}
//堆的调整:将元素A[k]自下往上逐步调整树形结构
private static void adjustHeap(int[] A, int k, int len) {
int tem=A[k];
for(int i=2*k+1;i<len;i=2*i+1){
if(i!=len-1 && A[i]<A[i+1]){
i++;//右>左,取右
}
if(tem>A[i]){
break;//根>右,结束
}else{
//否则,改变根植,并继续向下调整
A[k]=A[i];
k=i;//【关键】修改k值,以便继续向下调整
}
}
A[k]=tem; //被调整的结点的值放入最终位置
}
}
/**
* 希尔排序(不稳定)
* 时间复杂度:O(N*logN),步长越优,时间复杂度越低,步长越劣,越趋向n^2级别
* 空间复杂度:O(1)
* @author 98602
*
*/
public class ShellSort {
public int[] shellSort(int[] A, int n) {
if (A == null || n < 2)
return A;
int feet = n / 2;
int index = 0;
while (feet > 0) {
for (int i = feet; i < n; i++) {//插入排序
index = i;
while (index >= feet) {
if (A[index] < A[index - feet]) {//可以插就插,而不是将前面全部移到后面再插
swap(A, index, index - feet);
index -= feet;
} else {
break;
}
}
}
feet /= 2;//更新步伐
}
return A;
}
private void swap(int[] a, int feet, int index) {
int temp = a[feet];
a[feet] = a[index];
a[index] = temp;
}
}
/**
* 计数排序(基于桶排序)
* 时间复杂度:O(n)
* 空间复杂度:O(N),取决于桶的大小
* @author 98602
*
*/
public class CountingSort {
public static void main(String[] args) {
CountingSort c = new CountingSort();
c.countingSort(new int[]{1,2,3,5,2,3},6);
}
public int[] countingSort(int[] A, int n) {
if(A==null&&n<2)
return A;
int min = A[0];
int max = A[0];
for(int i : A){//取数的范围,决定桶的大小
min = Math.min(min,i);
max = Math.max(max,i);
}
int bucketLength = max - min + 1;//桶的大小
int[] bucket = new int[bucketLength];//建桶
for(int i=0;i<n;i++){//进桶
bucket[A[i]-min] ++;
}
int k = 0;
for(int i=0;i<bucketLength;i++){//倒桶
for(int j = 0;j<bucket[i];j++){
A[k++] = bucket[i] + min;
}
}
return A;
}
}