图解排序算法:
http://blog.csdn.net/middlekingt/article/details/8425686
java实现代码:
package com.algorithm;
/*
* java 八大排序算法
*/
public class Sort
{
//初始化数组的大小
private final static int MAX_SIZE = 10;
@SuppressWarnings("static-access")
public static void main(String[] args)
{
//产生数据
int[] bef_sort = new int[MAX_SIZE];
//为初始数组赋值
for(int i=0;iint)(100+Math.random()*(100+1));
}
System.out.println("排序前的数据为: ");
println(bef_sort);
System.out.println("排序后的数据为: ");
//冒泡排序
// new Mao_sort().sort(bef_sort);
//选择排序
// new Select_sort().sort(bef_sort);
//插入排序
// new Insert_sort().sort(bef_sort);
//希尔排序
// new Shell_sort().sort(bef_sort);
//快速排序
// new Quick_sort().sort(bef_sort);
//归并排序
// new Merging_Sort().sort(bef_sort, 0, bef_sort.length-1);
//基数排序
// new RadixSort().sort(bef_sort, bef_sort.length);
//堆排序
new HeapSort().heapSort(bef_sort);
println(bef_sort);
}
public static void println(int[] bef_sort){
//排序后的数组为:
for (int i = 0; i < bef_sort.length; i++)
{
System.out.print(bef_sort[i]+",");
}
System.out.println();
}
}
/*
* 冒泡排序:
* 两两比较,大数沉底
*/
class Mao_sort{
public static void sort(int[] a){
int temp;
for(int i=1;ifor(int j=0;jif(a[j]>a[j+1]){
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
}
/*
* 选择排序:
* 从数组中选出最小值和第一个交换
* 依次类推
*/
class Select_sort{
public static void sort(int[] a){
//定义两个变量 分别存放 可能被替换的数组下标 和中间替换值
int index;
int temp;
for(int i=0;i1;i++){
index = i;
for(int j=1;jif(a[j]if(index!=i){
temp = a[i];
a[i] = a[index];
a[index] = temp;
}
}
}
}
/*
* 插入排序:
* 前两个比较大小排序,第三个选择插入成序,后面一次类同
*/
class Insert_sort{
public void sort(int[] a){
//定义两个变量 分别存放插入位置 和 插入数值
int index,temp;
for(int i=1;i1;
temp = a[i];
while(index>=0 && a[index]>temp){
a[index+1] = a[index];
index--;
}
a[index+1] = temp;
}
}
}
/*
* Shell排序 缩小增量排序
* 将n个元素分成n/2个,第1个和第n/2+1为一对
* 一次循环使得一对排序
*/
class Shell_sort{
public void sort(int[] sort_shell){
int j,temp;
int i,r;
for(r=sort_shell.length/2;r>=1;r/=2){
for (i = r; i < sort_shell.length; i++)
{
temp =sort_shell[i];
j = i - r;
while(j>=0 && sort_shell[j]>temp){
sort_shell[j+r] = sort_shell[j];
j-=r;
}
sort_shell[j+r] = temp;
}
}
}
}
//快速排序
class Quick_sort{
public void sort(int[] arr){
quick_sort(arr, 0, arr.length-1);
}
//得到中的位置
public int getMiddle(int[] arr,int low ,int high){
int temp = arr[low];
while(lowwhile(low=temp){
high--;
}
arr[low] = arr[high];
while(lowreturn low;
}
public void quick_sort(int[] arr,int low,int high){
if(lowint middle = getMiddle(arr, low, high);
quick_sort(arr, low, middle-1);
quick_sort(arr, middle+1, high);
}
}
}
/*
* 归并排序
* 归并排序是将两个(或两个以上)有序表合并成一个新的有序表,
* 即把待排序系列分为若干个子系列,每个子系列是有序的,
* 然后再把有序子序列合并成整体有序序列。
* 时间复杂度为O(nlogn)
* 稳定排序方式
* @param nums 待排序数组
* @return 输出有序数组
*/
class Merging_Sort{
public void sort(int[] a,int left,int right){
//找出中间索引
int center = (left+right)/2;
if(left//对左边数组进行递归
sort(a, left, center);
//对右边数组进行递归
sort(a, center+1, right);
//左右合并
merge(a, left, center, right);
}
}
public static void merge(int[] nums, int low, int mid, int high) {
int[] temp = new int[high - low + 1];
int i = low;// 左指针
int j = mid + 1;// 右指针
int k = 0;
// 把较小的数先移到新数组中
while (i <= mid && j <= high) {
if (nums[i] < nums[j]) {
temp[k++] = nums[i++];
} else {
temp[k++] = nums[j++];
}
}
// 把左边剩余的数移入数组
while (i <= mid) {
temp[k++] = nums[i++];
}
// 把右边边剩余的数移入数组
while (j <= high) {
temp[k++] = nums[j++];
}
// 把新数组中的数覆盖nums数组
for (int k2 = 0; k2 < temp.length; k2++) {
nums[k2 + low] = temp[k2];
}
}
}
/*
* 基数排序
* 简介:基数排序法又称“桶子法”,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用
* 其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数
* 稳定排序方式
* @param nums 待排序数组
* @d 基数
*/
class RadixSort{
public static void sort(int[] nums,int d){
int k = 0;
int n = 1;
int len = nums.length;
//分成nums.length个桶
int[][] radixArray = new int[len][len];
//每个桶放的个数组成的数组
int[] tempArray = new int[len];
//还在位数内
while (n<=d) {
for (int i = 0; i < len; i++) {
//个,十,百,千...
int temp = (nums[i]/n)%10;
//存入特定桶的特定位置
radixArray[temp][tempArray[temp]] = nums[i];
tempArray[temp]++;
}
for (int i = 0; i < len; i++) {
if (tempArray[i] != 0) {
for (int j = 0; j < tempArray[i]; j++) {
//数组重组
nums[k] = radixArray[i][j];
k++;
}
//重置,以防下次循环时数据出错
tempArray[i] = 0;
}
}
//重置,以防下次循环时数据出错
k = 0;
//进位
n *=10;
}
}
}
/*
* 堆排序:
* 堆是一种重要的数据结构,为一棵完全二叉树, 底层如果用数组存储数据的话,
* 假设某个元素为序号为i(Java数组从0开始,i为0到n-1),
* 如果它有左子树,那么左子树的位置是2i+1,如果有右子树,右子树的位置是2i+2,
* 如果有父节点,父节点的位置是(n-1)/2取整。
* 分为最大堆和最小堆,最大堆的任意子树根节点不小于任意子结点,最小堆的根节点不大于任意子结点。
* 所谓堆排序就是利用堆这种数据结构来对数组排序,我们使用的是最大堆。
* 处理的思想和冒泡排序,选择排序非常的类似,一层层封顶,只是最大元素的选取使用了最大堆。
* 最大堆的最大元素一定在第0位置,构建好堆之后,交换0位置元素与顶即可。
* 堆排序为原位排序(空间小), 且最坏运行时间是O(n2),是渐进最优的比较排序算法。
*/
/*
* 堆排序的大概步骤如下:
* 1、构建最大堆。
* 2、选择顶,并与第0位置元素交换
* 3、由于步骤2的的交换可能破环了最大堆的性质,第0不再是最大元素,需要调用maxHeap调整堆(沉降法),如果需要重复步骤2
*
* 堆排序中最重要的算法就是maxHeap,该函数假设一个元素的两个子节点都满足最大堆的性质(左右子树都是最大堆),
* 只有跟元素可能违反最大堆性质,那么把该元素以及左右子节点的最大元素找出来,
* 如果该元素已经最大,那么整棵树都是最大堆,程序退出,否则交换跟元素与最大元素的位置,
* 继续调用maxHeap原最大元素所在的子树。该算法是分治法的典型应用。
* 具体代码如下:
*
*/
class HeapSort {
public static void heapSort(int[] array) {
if (array == null || array.length <= 1) {
return;
}
buildMaxHeap(array);
for (int i = array.length - 1; i >= 1; i--) {
exchangeElements(array, 0, i);
maxHeap(array, i, 0);
}
}
private static void buildMaxHeap(int[] array) {
if (array == null || array.length <= 1) {
return;
}
int half = array.length / 2;
for (int i = half; i >= 0; i--) {
maxHeap(array, array.length, i);
}
}
private static void maxHeap(int[] array, int heapSize, int index) {
int left = index * 2 + 1;
int right = index * 2 + 2;
int largest = index;
if (left < heapSize && array[left] > array[index]) {
largest = left;
}
if (right < heapSize && array[right] > array[largest]) {
largest = right;
}
if (index != largest) {
exchangeElements(array, index, largest);
maxHeap(array, heapSize, largest);
}
}
public static void exchangeElements(int[] array, int index1, int index2) {
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
}