您的位置:首页 > 职场人生

程序员必知的8大排序

2016-04-14 13:07 471 查看


1, 直接插入排序

(1)基本思想:在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。

(2)java实现

package sort;

public class InsertSort {
public static void main(String[] args) {
int[] source={591,401,874,141,348,72,911,887,820,283};
sort(source);
System.out.println(source[0]+","+source[1]+","+source[2]+","+source[3]+","+source[4]+","+source[5]+","+source[6]+","+source[7]+","+source[8]+","+source[9]);
}
public static void sort(int[] source){
for (int i = 1; i < source.length; i++) {
int temp=source[i];
int j =i-1;
for (; (j >=0&&source[j]>temp); j--) {
source[j+1]=source[j];
}
source[j+1]=temp;
}
}
}


2,希尔排序

(1)基本思想:算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行直接插入排序后,排序完成。希尔排序是不稳定的。

(2)java实现
package sort;

public class ShellSort {
public static void main(String[] args) {
int[] source={591,401,874,141,348,72,911,887,820,283};
sort(source);
System.out.println(source[0]+","+source[1]+","+source[2]+","+source[3]+","+source[4]+","+source[5]+","+source[6]+","+source[7]+","+source[8]+","+source[9]);

}
public static void sort(int[] source){
for (int h=source.length/2;h>0;h=h/2) {
//			进行插入排序
for (int i = h; i < source.length; i+=h) {
int temp=source[i];
int j =i-h;
for (; (j >=0&&source[j]>temp); j-=h) {
source[j+h]=source[j];
}
source[j+h]=temp;
}
}
}
}


3,简单选择排序

(1)基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。

(2)java实现

package sort;

public class selectSort {
public static void main(String[] args) {
int[] source={591,401,874,141,348,72,911,887,820,283};
sort(source);
System.out.println(source[0]+","+source[1]+","+source[2]+","+source[3]+","+source[4]+","+source[5]+","+source[6]+","+source[7]+","+source[8]+","+source[9]);
}
public static void sort(int[] source){
for (int i = 1; i < source.length; i++) {
int location=i-1;
int min=source[i-1];
for (int j=i;j<source.length;j++) {
if(source[j]<min){
min=source[j];
location=j;
}
}
if(location!=i-1){
source[location]=source[i-1];
source[i-1]=min;
}
}
}
}


4,堆排序

(1)基本思想:采用最大堆的实现方式,k[i]>k[2i],k[i]>k[2i+1],k=[1,n/2]。java数字是从0开始的,所有对应规则为:k[i]>k[2i+1],k[i]>k[2i+2],k=[0,(n-1)/2]。

(2)java实现

package sort;

import java.util.Arrays;

public class HeapSort {

public static void main(String[] args) {
int a[] = {591,401,874,141,348,72,911,887,820,283};
heapSort(a);
}

public static void heapSort(int[] a) {
int arrayLength = a.length;
// 循环建堆
for (int i = 0; i < arrayLength - 1; i++) {
// 建堆
buildMaxHeap(a, arrayLength - 1 - i);
// 交换堆顶和最后一个元素
swap(a, 0, arrayLength - 1 - i);
}
System.out.println(Arrays.toString(a));
}
private static void swap(int[] data, int i, int j) {
// TODO Auto-generated method stub
int tmp = data[i];
data[i] = data[j];
data[j] = tmp;
}
// 对data数组从0到lastIndex建大顶堆
private static void buildMaxHeap(int[] data, int lastIndex) {
// 从lastIndex处节点(最后一个节点)的父节点开始
for (int i = (lastIndex) / 2; i >= 0; i--) {
// k保存正在判断的节点
int k = i;
// 如果当前k节点的子节点存在
while (k * 2 + 1 <= lastIndex) {
// k节点的左子节点的索引
int biggerIndex = 2 * k + 1;
// 如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在
if (biggerIndex < lastIndex) {
// 若果右子节点的值较大
if (data[biggerIndex] < data[biggerIndex + 1]) {
// biggerIndex总是记录较大子节点的索引
biggerIndex++;
}
}
// 如果k节点的值小于其较大的子节点的值
if (data[k] < data[biggerIndex]) {
// 交换他们
swap(data, k, biggerIndex);
// 将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
k = biggerIndex;
} else {
break;
}
}
}
}
}


5,冒泡排序

(1)基本思想:它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。每次走访都将最大或者最小值放到了数字中最后一个位置,然后对之前的数据在进行走访。

(2)java实现
package sort;

public class BubbleSort{
public static void main(String[] args) {
int[] source={591,401,874,141,348,72,911,887,820,283};
sort(source);
System.out.println(source[0]+","+source[1]+","+source[2]+","+source[3]+","+source[4]+","+source[5]+","+source[6]+","+source[7]+","+source[8]+","+source[9]);
}
public static void sort(int[] source){
for (int i = 0; i < source.length-1; i++) {
for ( int j=0; j < source.length-1-i; j++) {
if(source[j]<source[j+1]){
swap(source, j, j+1);
}
}
}
}
private static void swap(int[] data, int i, int j) {
int tmp = data[i];
data[i] = data[j];
data[j] = tmp;
}
}


6,快速排序

(1)基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

(2)java实现

package sort;

public class QuickSort {
public static void main(String[] args) {
int[] source={591,401,874,141,348,72,911,887,820,283};
quickSort(source);
System.out.println(source[0]+","+source[1]+","+source[2]+","+source[3]+","+source[4]+","+source[5]+","+source[6]+","+source[7]+","+source[8]+","+source[9]);
}
public static void quickSort(int[] array){
if(array != null){
quickSort(array, 0, array.length-1);
}
}
private static void quickSort(int[] array,int beg,int end){
if(beg >= end || array == null)
return;
int p = partition(array, beg, end);
quickSort(array, beg, p-1);
quickSort(array, p+1, end);
}
private static int partition(int[] array, int beg, int end) {
int first = array[beg];
int i = beg, j = end;
while (i < j) {
while (array[i] <= first && i < end) {
i++;
}
while (array[j] > first && j >= beg) {
j--;
}
if (i < j) {
array[i] = array[i] ^ array[j];
array[j] = array[i] ^ array[j];
array[i] = array[i] ^ array[j];
}
}
if (j != beg) {
array[j] = array[beg] ^ array[j];
array[beg] = array[beg] ^ array[j];
array[j] = array[beg] ^ array[j];
}
return j;
}
}


7,归并排序

(1)基本思想:假设初始序列有n个记录,则可以看成是n个有序的子序列,每一个子序列的长度为1,然后两两归并,得到[n/2]个长度为2或者1的有序子序列;再两两归并......,如此重复,知道得到一个长度为n的有序序列为止。

(2)java实现
package sort;

import java.util.Arrays;

public class MergeSort {
/**
* 归并排序
* 简介:将两个(或两个以上)有序表合并成一个新的有序表 即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列
* 时间复杂度为O(nlogn)
* 稳定排序方式
* @param nums 待排序数组
* @return 输出有序数组
*/
public static int[] sort(int[] nums, int low, int high) {
int mid = (low + high) / 2;
if (low < high) {
// 左边
sort(nums, low, mid);
// 右边
sort(nums, mid + 1, high);
// 左右归并
merge(nums, low, mid, high);
}
return nums;
}

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];
}
}
// 归并排序的实现
public static void main(String[] args) {
int[] source={591,401,874,141,348,72,911,887,820,283};
sort(source, 0, source.length-1);
System.out.println(Arrays.toString(source));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: