冒泡排序
package com.test;
/**
* 冒泡排序
*
* 时间复杂度为:o(n`2) 空间复杂度为o(1)
*
* 最好最坏复杂度都是o(n`2)
*
* 说明:
* 对当前还未排序的所有数,自上而下对相邻的两个数依次进行比较和调整,
* 让较大的数日后面移动 , 让较小的数往前面移动
*
* 算法比较稳定 为两两比较 不存在跳跃
*
* Created by abing on 2015/11/26.
*/
public class SuanFaBubble {
public static void main(String[] args){
int[] a = {1,2,6,5,4,3,23,43,123,432};
sort(a);
}
public static void sort(int[] arr){
int tmp = 0;
for ( int i = 0 ; i < arr.length - 1 ; i++ ){
for (int j = 0 ; j < arr.length - 1 - i ; j++){
if (arr[j] > arr[j+1]){
tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
for (int a : arr){
System.out.print(a + " ");
}
}
}
基数排序
package com.test;
import java.util.ArrayList;
import java.util.List;
/**
* 基数排序
*
* 时间复杂度为o(n+k)
* 最好最坏都同样
*
* 说明:
* 将全部待比较数值(正整数)统一为一样的数位长度,数位较短的数前面补零。
* 而后,从最低位开始,依次进行一次排序。
* 这样从最低位排序一直到最高位排序完成之后,数列就变成一个有序序列
*
* Created by abing on 2015/11/26.
*/
public class SuanFaCount {
public static void main(String[] args){
int[] array ={1,3,6,2,5,87,54,32,21,22,33,44,11};
sort(array);
for (int a : array){
System.out.print(a + " ");
}
}
public static void sort(int[] array){
//首先肯定排序的趟数;
int max=array[0];
for(int i=1;i<array.length;i++){
if(array[i]>max){
max=array[i];
}
}
int time=0;
//判断位数;
while(max>0){
max/=10;
time++;
}
//创建10个队列;
List<ArrayList> queue=new ArrayList<ArrayList>();
for(int i=0;i<10;i++){
ArrayList<Integer>queue1=new ArrayList<Integer>();
queue.add(queue1);
}
//进行time次分配和收集;
for(int i=0;i<time;i++){
//分配数组元素;
for(int j=0;j<array.length;j++){
//获得数字的第time+1位数;
int x=array[j]%(int)Math.pow(10,i+1)/(int)Math.pow(10, i);
ArrayList<Integer>queue2=queue.get(x);
queue2.add(array[j]);
queue.set(x, queue2);
}
int count=0;//元素计数器;
//收集队列元素;
for(int k=0;k<10;k++){
while(queue.get(k).size()>0){
ArrayList<Integer>queue3=queue.get(k);
array[count]=queue3.get(0);
queue3.remove(0);
count++;
}
}
}
}
}
快速排序
package com.test;
/**
* 快速排序
*
* 时间复杂度为o(nlogn) 空间复杂度为o(logn)
*
* 最坏O(n^2) 当划分不均匀时候 逆序and排好序都是最坏状况
最好O(n) 当划分均匀
partition的时间复杂度: O(n)一共须要logn次partition
*
*说明:
* 选择一个基准元素,一般选择第一个元素或者最后一个元素,经过一趟扫描,将待排序列分红两部分,
* 一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,而后再用一样的方法递归地排序划分的两部分。
*
* Created by abing on 2015/11/26.
*/
public class SuanFaFast {
public static void main(String[] args){
int[] aa = {1,4,6,2,5,8,21,43,22,44,33};
quick(aa);
for (int a : aa){
System.out.print(a + " ");
}
}
public static void quick(int[] arr){
if (arr.length > 0){
quickSort(arr , 0 ,arr.length - 1);
}
}
public static void quickSort(int[] arr , int low , int high){
if (low < high){
int middle = getMiddle(arr , low ,high); //将list一份为二
quickSort(arr , low , middle - 1); //对低字表进行递归排序
quickSort(arr , middle + 1 , high); //对高字表进行递归排序
}
}
public static int getMiddle(int[] arr , int low , int high){
int tmp = arr[low]; //数组的第一个做为中轴
while (low < high){
while (low < high && arr[high] >= tmp){
high--;
}
arr[low] = arr[high]; //比中轴小的记录移到低端
while (low < high && arr[low] <= tmp){
low++;
}
arr[high] = arr[low]; //比中轴大的记录移到高端
}
arr[low] = tmp; //中轴记录到尾
return low; //返回中轴记录
}
}
希尔排序
package com.test;
/**
* 希尔排序
*
* 时间复杂度o(n`1.2)
*
* 说明:
* 算法先将要排序的一组数按照某个增量d(n/2 , m为要排序的个数)分为若干组 , 每组中记录的下标相差d,
* 对每组中所有元素进行直接插入排序。而后再用一个较小的增量(d/2)对它进行分组,在每组中再进行插入排序。
* 当增量减小到1的时候,进行直接插入排序后。排序完成。
*
*
* Created by abing on 2015/11/26.
*/
public class SuanFaHill {
public static void main(String[] args){
int[] arr = {1,8,4,2,6,12,34,21,33,55,11,88,33};
sort(arr);
}
public static void sort(int[] arr){
double d1 = arr.length;
int tmp = 0 ;
while (true) {
d1 = Math.ceil(d1/2);
int d = (int) d1;
for (int x = 0 ; x < d ; x++){
for (int i = x+d ; i < arr.length ; i+=d){
int j = i -d;
tmp = arr[i];
while (j >=0 && tmp <arr[j]){
arr[j+d] = arr[j];
j -=d;
}
arr[j+d] = tmp;
}
}
if (d == 1){
break;
}
}
for (int a : arr){
System.out.print(a + " ");
}
}
}
插入排序
package com.test;
/**
* 插入排序
* 时间复杂度 o(n`2) 控件复杂度 o(1)
*
* 最好为n 最坏复杂度为n`2
*
* 说明:
* 从头开始排序 若是后面有比前面小的直接插入其中
*
* Created by abing on 2015/11/26.
*/
public class SuanFaInsert {
public static void main(String[] args){
int[] a = {1,2,6,5,4,3,23,43,123,432};
sortWhile(a);
}
/**
* 这一种使用的是两层for循环进行排序
* @param arr
*/
public static void sort(int[] arr){
int tmp = 0;
for (int i = 0 ; i < arr.length ; i++) {
for (int j = i-1 ; j >= 0 ; j--){
if (arr[j+1] < arr[j]){
tmp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = tmp;
}
}
}
for (int a : arr){
System.out.print(a + " ");
}
}
/**
* 本循环与上面的差很少 只不过是使用了while循环
* @param arr
*/
public static void sortWhile(int[] arr){
int tmp = 0;
for (int i = 1 ; i < arr.length ; i++) {
int j = i-1;
while (arr[j+1] < arr[j]){
tmp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = tmp;
j--;
}
}
for (int a : arr){
System.out.print(a + " ");
}
}
}
归并排序
package com.test;
import java.util.Arrays;
/**
* 归并排序
*
* 时间复杂度为o(nlogn) 空间复杂度为 o(n) + o(logn)
*
* 说明:
* 把两个(或者两个以上)的有序表合并成一个新的有序表 , 把待排序序列分为若干个序列 , 每一个子序列都是有序的
* 而后再把有序的子序列合并为总体有序序列
*
* Created by abing on 2015/11/26.
*/
public class SuanFaMerge {
public static void main(String[] args){
int[] data = {1,2,3,5,21,43,65,87,22,33,44,55,99};
sort(data , 0 , data.length-1);
}
public static void sort(int[] data , int left , int right){
if (left < right){
int center = (right + left)/2;
System.out.println("11 : "+left + " " + center + " " + right);
sort(data, left, center);
System.out.println("22 : "+left + " " + center + " " + right);
sort(data, center + 1, right);
System.out.println("33 : "+left + " " + center + " " + right);
merge(data , left ,center , right);
}
}
public static void merge(int[] data , int left , int center , int right){
// System.out.println(left + " " + center + " " + right);
int[] tmpArr = new int[data.length];
int mid = center+1;
//记录中间数组的索引
int third = left;
int tmp = left;
while (left <= center && mid <= right){
//从两个数组中取出最小的放入中间数组
if (data[left] <= data[mid]){
tmpArr[third++] = data[left++];
}else {
tmpArr[third++] = data[mid++];
}
}
//剩余部分依次放入中间数组
while (mid <= right){
tmpArr[third++] = data[mid++];
}
while (left <= center){
tmpArr[third++] = data[left++];
}
//将中间数组中的内容复制回原数组
while (tmp <= right){
data[tmp] = tmpArr[tmp++];
}
System.out.println(Arrays.toString(data));
}
}
选择排序
package com.test;
/**
* 选择排序 时间复杂度为o(n`2) 空间复杂度为o(1)
*
* 没有最好最坏的状况 排序时间都是同样的
*
* 说明:
* 从头开始排序 从后面选择最小的与第一个交换 而后再从后面选择最小的与第二个进行交互
*
* 知道交换到倒数第二个与倒数第一个进行交换
*
* Created by abing on 2015/11/26.
*/
public class SuanFaSelect {
public static void main(String[] args){
int[] arr ={1,4,7,3,22,65,44,22,88,54,76,31,32};
sort(arr);
}
public static void sort(int[] arr){
for (int i = 0 ; i < arr.length -1 ; i++){
int min = i;
int tmp;
for (int j = i+1 ; j < arr.length ; j++){
if (arr[j] < arr[min]){
min = j;
}
}
if (min != i){
tmp = arr[min];
arr[min] = arr[i];
arr[i] = tmp;
}
}
for (int a : arr){
System.out.print(a + " ");
}
}
}
堆排序
package com.test;
import java.util.Arrays;
/**
* 堆排序
*
* 时间复杂度o(nlogn) 空间复杂度o(1)
*
* 没有最好与最坏的区别 时间复杂度都是o(nlogn) 不是很稳定的算法
*
* 说明:
*具备n个元素的序列(h1,h2,...,hn),当且仅当知足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)时称之为堆。
* 在这里只讨论知足前者条件的堆。由堆的定义能够看出,堆顶元素(即第一个元素)必为最大项(大顶堆)。彻底二叉树能够很直观地表示堆的结构。
* 堆顶为根,其它为左子树、右子树。初始时把要排序的数的序列看做是一棵顺序存储的二叉树,调整它们的存储序,使之成为一个堆,
* 这时堆的根节点的数最大。而后将根节点与堆的最后一个节点交换。而后对前面(n-1)个数从新调整使之成为堆。
* 依此类推,直到只有两个节点的堆,并对它们做交换,最后获得有n个节点的有序序列。
* 从算法描述来看,堆排序须要两个过程,一是创建堆,二是堆顶与堆的最后一个元素交换位置。
* 因此堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。
*
*
* 对于大数据的处理呢,若是对100亿条数据选择Topk数据,选择快速排序好仍是堆排序好?
* 答案是只能用堆排序。
* 堆排序只须要维护一个k大小的空间,即在内存开辟k大小的空间。而快速排序须要开辟能存储100亿条数据的空间
*
* Created by abing on 2015/11/26.
*/
public class SuanFaStack {
public static void main(String[] args){
int[] a = {3,1,4,6,2,43,21,65,22,44,88,11};
headSort(a);
for (int i : a){
System.out.print(i + " ");
}
}
public static void headSort(int[] arr){
int arrlength = arr.length;
for (int i = 0 ; i < arrlength - 1 ; i++){
buildMaxHeap(arr, arrlength - 1 - i);
swap(arr, 0, arrlength - 1 - i);
System.out.println(Arrays.toString(arr));
}
}
public static void swap(int[] arr , int i , int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void buildMaxHeap(int[] data , int lastIndex){
for (int i = (lastIndex-1)/2 ; i >= 0 ; i--){
int k = i;
while (k*2 + 1 <= lastIndex){
int biggerIndex = 2*k + 1;
if (biggerIndex < lastIndex){
if (data[biggerIndex] < data[biggerIndex+1]){
biggerIndex++;
}
}
if (data[k] < data[biggerIndex]){
swap(data , k , biggerIndex);
k = biggerIndex;
}else {
break;
}
}
}
}
}