您的位置:首页 > 编程语言 > Java开发

Java 几种排序法

2010-04-30 10:30 337 查看
这里主要对8种排序算法做个总结,分别是插入排序,选择排序,冒泡排序,希尔排序,归并排序,堆排序,快速排序以及基数排序。

1、 插入排序

比较和交换的时间复杂度为O(n^2),算法自适应,对于数据已基本有序的情况,时间复杂度为O(n),算法稳定,开销很低,适合于数据已基本有序或者数据量小的情况。

public void insertionSort() {// 插入排序

int out, in;

int count1 = 0, count2 = 0;// 复制次数,比较次数

for (out = 1; out < nElems; out++) {

long temp = a[out];

in = out;

boolean flag=in>0&&a[in-1]>=temp;

while(flag){

if(a[in-1]>=temp){

if(in>0){

a[in]=a[in-1];

count1++;

--in;

}

}

count2++;

flag=in>0&&a[in-1]>=temp;

}

a[in] = temp;

}

System.out.println("复制次数为:" + count1 + " 比较次数为:" + count2);

}


2、 选择排序

算法不稳定,O(1)的额外的空间,比较的时间复杂度为O(n^2),交换的时间复杂度为O(n),并不是自适应的。在大多数情况下都不推荐使用。只有在希望减少交换次数的情况下可以用。

public void selectionSort(){//选择排序

int out, in, min;

for(out=0;out<nElems-1;out++){

min=out;

for(in=out+1;in<nElems;in++){

if(a[in]<a[min]){

min=in;

}

swap(out,min);

}

}

}


3、 冒泡排序

算法稳定,O(1)的额外的空间,比较和交换的时间复杂度都是O(n^2),自适应,对于已基本排序的算法,时间复杂度为O(n)。冒泡算法的许多性质和插入算法相似,但对于系统开销高一点点。

public void bubbleSort() {// 冒泡排序,单项

int out, in;

for (out = nElems - 1; out > 1; out--) {

for (in = 0; in < out; in++) {

if (a[in] > a[in + 1]) {

swap(in, in + 1);

}

}

}

}


4、 希尔排序

希尔排序并不稳定,O(1)的额外空间,时间复杂度为O(N*(logN)^2)。这中算法是基于插入排序的。最坏的情况下的执行效率和在平均情况下的执行效率相比相差不多。
public void shellSort(){

int inner, outer;

long temp;

int h=1;

while(h<nElems/3){

h=h*3+1;

}//Knuth序列初始化

while(h>0){

for(outer=h;outer<nElems;outer++){

temp = theArray[outer];

inner = outer;

while((inner>h-1)&&theArray[inner-h]>=temp){

theArray[inner]=theArray[inner];

inner-=h;

}

theArray[inner]=temp;

}

h=(h-1)/3;

}

}


5、 归并排序

归并算法稳定,数组需要O(n)的额外空间,链表需要O(log(n))的额外空间,时间复杂度为O(nlog(n)),算法不是自适应的,不需要对数据的随机读取。

public void mergeSort(){

long[] workSpace = new long[nElems];

recMergeSort(workSpace,0,nElems-1);

}

private void recMergeSort(long[] workSpace, int lowerBound, int upperBound){

if(lowerBound == upperBound){

return;

}

else{

int mid=(lowerBound+upperBound)/2;

recMergeSort(workSpace, lowerBound, mid);

recMergeSort(workSpace, mid+1, upperBound);

merge(workSpace, lowerBound, mid+1, upperBound);

}

}

private void merge(long[] workSpace, int lowPtr, int highPtr, int upperBound){

int j = 0;

int lowerBound = lowPtr;

int mid = highPtr - 1;

int n = upperBound-lowerBound+1;

while(lowPtr<=mid&&highPtr<=upperBound){

if(theArray[lowPtr]<theArray[highPtr]){

workSpace[j++]=theArray[lowPtr++];

}

else{

workSpace[j++]=theArray[highPtr++];

}

}

while(lowPtr<=mid){

workSpace[j++] = theArray[lowPtr++];

}

while(highPtr<=upperBound){

workSpace[j++] = theArray[highPtr++];

}

for(j=0;j<n;j++){

theArray[lowerBound+j]=workSpace[j];

}

}


6、java堆排序的实现

import java.io.IOException;

class MyNode {
private int iData;

public MyNode(int key) {
iData = key;
}

public int getKey() {
return iData;
}

}

public class Heap {
private MyNode[] heapArray;

private int maxSize;

private int currentSize; // number of items in array

public Heap(int mx) {
maxSize = mx;
currentSize = 0;
heapArray = new MyNode[maxSize];
}

public MyNode remove()
{
MyNode root = heapArray[0];
heapArray[0] = heapArray[--currentSize];
trickleDown(0);
return root;
}

public void trickleDown(int index) {
int largerChild;
MyNode top = heapArray[index];
while (index < currentSize / 2)
{
int leftChild = 2 * index + 1;
int rightChild = leftChild + 1;
// 找到最大的子节点
if (rightChild < currentSize
&&
heapArray[leftChild].getKey() < heapArray[rightChild]
.getKey())
largerChild = rightChild;
else
largerChild = leftChild;

if (top.getKey() >= heapArray[largerChild].getKey())
break;

heapArray[index] = heapArray[largerChild];
index = largerChild;
}
heapArray[index] = top;
}

public void displayHeap() {
int nBlanks = 32;
int itemsPerRow = 1;
int column = 0;
int currentIndex = 0;
while (currentSize > 0)
{
if (column == 0)
for (int k = 0; k < nBlanks; k++)
System.out.print(' ');
System.out.print(heapArray[currentIndex].getKey());

if (++currentIndex == currentSize) //  判断是否输出结束
break;

if (++column == itemsPerRow) // 是否到达行尾?
{
nBlanks /= 2;
itemsPerRow *= 2;
column = 0;
System.out.println();
} else
for (int k = 0; k < nBlanks * 2 - 2; k++)
System.out.print(' '); // 输入空白
}
}

public void displayArray() {
for (int j = 0; j < maxSize; j++)
System.out.print(heapArray[j].getKey() + " ");
System.out.println("");
}

public void insertAt(int index, MyNode newNode) {
heapArray[index] = newNode;
}

public void incrementSize() {
currentSize++;
}

public static void main(String[] args) throws IOException {
int size, i;

size = 100;
Heap theHeap = new Heap(size);

for (i = 0; i < size; i++) {
int random = (int) (java.lang.Math.random() * 100);
MyNode newNode = new MyNode(random);
theHeap.insertAt(i, newNode);
theHeap.incrementSize();
}

System.out.print("Random: ");
theHeap.displayArray();
for (i = size / 2 - 1; i >= 0; i--)
theHeap.trickleDown(i);

System.out.print("Heap:   ");
theHeap.displayArray();
theHeap.displayHeap();
for (i = size - 1; i >= 0; i--) {
MyNode biggestNode = theHeap.remove();
theHeap.insertAt(i, biggestNode);
}
System.out.print("Sorted: ");
theHeap.displayArray();
}
}


7、 快速排序

快速排序不稳定,O(log(n))的额外空间,时间复杂度为O(nlog(n)),不是自适应的。

public void quickSort(){

recQuickSort(0,nElems-1);

}

public void recQuickSort(int left, int right){

if(right-left<=0){

return;

}else{

long pivot = theArray[right];

int partition = partitionIt(left, right, pivot);

recQuickSort(left, partition-1);

recQuickSort(partition+1, right);

}

}

public int partitionIt(int left, int right, long pivot){

int leftPtr = left -1;

int rightPtr = right;

while(true){

while(theArray[++leftPtr]<pivot);

while(rightPtr>0&&theArray[--rightPtr]>pivot);

if(leftPtr>=rightPtr){

break;

}else{

swap(leftPtr,rightPtr);

}

}swap(leftPtr,right);

return leftPtr;

}

public void swap(int dex1, int dex2){

long temp;

temp = theArray[dex1];

theArray[dex1]=theArray[dex2];

theArray[dex2]=temp;

}


8、 基数排序

以基数是10为例

① 根据数据项个位上的值,把所有的数据分为10组。

② 然后对这10组数据项重新排列:把所有关键字是以0结尾的数据排在最后面,然后是关键字结尾时1的数据项,照此顺序直到以9结尾的数据项。这个步骤被称为第一趟子排序。

③ 在第二趟子排序中,再次把所有的数据项分为10组,但是这一次是根据数据项十位上的值来分组。这次分组不能改变先前的排序顺序。也就是说,第二趟排序之后,从每一组数据项的内部来看,数据项的顺序保持不变;这趟排序必须是稳定。

④ 然后再把10组数据项重新合并,排在最前面的是十位上为0的数据项,然后是十位为1的数据项,如此排序到十位上为9的数据项

⑤ 对剩余位重复这个过程。如果某些数据项的位数少于其他数据项的,那么认为他们的最高位为0

public static int[] countSort(int[] a, int k) {

int[] b = new int[a.length];

int[] c = new int[10];

for (int i = 0; i < b.length; i++) {

b[i] = 0;

}

for (int i = 0; i < c.length; i++) {

c[i] = 0;

}

int s = 1;

for (int i = 0; i < k; i++) {

s = s * 10;

}

int temp1 = 0;

for (int i = 0; i < a.length; i++) {

temp1 = a[i] % s;

temp1 = temp1 * 10 / s;

c[temp1] = c[temp1] + 1;

}

for (int i = 1; i < c.length; i++) {

c[i] = c[i] + c[i - 1];

}

int temp2 = 0;

for (int i = a.length - 1; i >= 0; i--) {

temp1 = a[i];

temp2 = a[i] % s;

temp2 = temp2 * 10 / s;

b[c[temp2] - 1] = temp1;

c[temp2] = c[temp2] - 1;

}

return b;

}


排序测试代码:

package com.softeem.jbs.lesson4;

import java.util.Random;

/**

* 排序测试类

*

* 排序算法的分类如下:

* 1.插入排序(直接插入排序、折半插入排序、希尔排序);

* 2.交换排序(冒泡泡排序、快速排序);

* 3.选择排序(直接选择排序、堆排序);

* 4.归并排序;

* 5.基数排序。

*

* 关于排序方法的选择:

* (1)若n较小(如n≤50),可采用直接插入或直接选择排序。

*  当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插人,应选直接选择排序为宜。

* (2)若文件初始状态基本有序(指正序),则应选用直接插人、冒泡或随机的快速排序为宜;

* (3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或归并排序。

*

*/

public class SortTest {

/**

* 初始化测试数组的方法

* @return 一个初始化好的数组

*/

public int[] createArray() {

Random random = new Random();

int[] array = new int[10];

for (int i = 0; i < 10; i++) {

array[i] = random.nextInt(100) - random.nextInt(100);//生成两个随机数相减,保证生成的数中有负数

}

System.out.println("==========原始序列==========");

printArray(array);

return array;

}

/**

* 打印数组中的元素到控制台

* @param source

*/

public void printArray(int[] data) {

for (int i : data) {

System.out.print(i + " ");

}

System.out.println();

}

/**

* 交换数组中指定的两元素的位置

* @param data

* @param x

* @param y

*/

private void swap(int[] data, int x, int y) {

int temp = data[x];

data[x] = data[y];

data[y] = temp;

}

/**

* 冒泡排序----交换排序的一种

* 方法:相邻两元素进行比较,如有需要则进行交换,每完成一次循环就将最大元素排在最后(如从小到大排序),下一次循环是将其他的数进行类似操作。

* 性能:比较次数O(n^2),n^2/2;交换次数O(n^2),n^2/4

*

* @param data 要排序的数组

* @param sortType 排序类型

* @return

*/

public void bubbleSort(int[] data, String sortType) {

if (sortType.equals("asc")) { //正排序,从小排到大

//比较的轮数

for (int i = 1; i < data.length; i++) {

//将相邻两个数进行比较,较大的数往后冒泡

for (int j = 0; j < data.length - i; j++) {

if (data[j] > data[j + 1]) {

//交换相邻两个数

swap(data, j, j + 1);

}

}

}

} else if (sortType.equals("desc")) { //倒排序,从大排到小

//比较的轮数

for (int i = 1; i < data.length; i++) {

//将相邻两个数进行比较,较大的数往后冒泡

for (int j = 0; j < data.length - i; j++) {

if (data[j] < data[j + 1]) {

//交换相邻两个数

swap(data, j, j + 1);

}

}

}

} else {

System.out.println("您输入的排序类型错误!");

}

printArray(data);//输出冒泡排序后的数组值

}

/**

* 直接选择排序法----选择排序的一种

* 方法:每一趟从待排序的数据元素中选出最小(或最大)的一个元素, 顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。

* 性能:比较次数O(n^2),n^2/2

*       交换次数O(n),n

*       交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CUP时间多,所以选择排序比冒泡排序快。

*       但是N比较大时,比较所需的CPU时间占主要地位,所以这时的性能和冒泡排序差不太多,但毫无疑问肯定要快些。

*

* @param data 要排序的数组

* @param sortType 排序类型

* @return

*/

public void selectSort(int[] data, String sortType) {

if (sortType.equals("asc")) { //正排序,从小排到大

int index;

for (int i = 1; i < data.length; i++) {

index = 0;

for (int j = 1; j <= data.length - i; j++) {

if (data[j] > data[index]) {

index = j;

}

}

//交换在位置data.length-i和index(最大值)两个数

swap(data, data.length - i, index);

}

} else if (sortType.equals("desc")) { //倒排序,从大排到小

int index;

for (int i = 1; i < data.length; i++) {

index = 0;

for (int j = 1; j <= data.length - i; j++) {

if (data[j] < data[index]) {

index = j;

}

}

//交换在位置data.length-i和index(最大值)两个数

swap(data, data.length - i, index);

}

} else {

System.out.println("您输入的排序类型错误!");

}

printArray(data);//输出直接选择排序后的数组值

}

/**

* 插入排序

* 方法:将一个记录插入到已排好序的有序表(有可能是空表)中,从而得到一个新的记录数增1的有序表。

* 性能:比较次数O(n^2),n^2/4

*       复制次数O(n),n^2/4

*       比较次数是前两者的一般,而复制所需的CPU时间较交换少,所以性能上比冒泡排序提高一倍多,而比选择排序也要快。

*

* @param data 要排序的数组

* @param sortType 排序类型

*/

public void insertSort(int[] data, String sortType) {

if (sortType.equals("asc")) { //正排序,从小排到大

//比较的轮数

for (int i = 1; i < data.length; i++) {

//保证前i+1个数排好序

for (int j = 0; j < i; j++) {

if (data[j] > data[i]) {

//交换在位置j和i两个数

swap(data, i, j);

}

}

}

} else if (sortType.equals("desc")) { //倒排序,从大排到小

//比较的轮数

for (int i = 1; i < data.length; i++) {

//保证前i+1个数排好序

for (int j = 0; j < i; j++) {

if (data[j] < data[i]) {

//交换在位置j和i两个数

swap(data, i, j);

}

}

}

} else {

System.out.println("您输入的排序类型错误!");

}

printArray(data);//输出插入排序后的数组值

}

/**

* 反转数组的方法

* @param data 源数组

*/

public void reverse(int[] data) {

int length = data.length;

int temp = 0;//临时变量

for (int i = 0; i < length / 2; i++) {

temp = data[i];

data[i] = data[length - 1 - i];

data[length - 1 - i] = temp;

}

printArray(data);//输出到转后数组的值

}

/**

* 快速排序

* 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。

* 步骤为:

* 1. 从数列中挑出一个元素,称为 "基准"(pivot),

* 2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分割之后,该基准是它的最后位置。这个称为分割(partition)操作。

* 3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

* 递回的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递回下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

* @param data 待排序的数组

* @param low

* @param high

* @see SortTest#qsort(int[], int, int)

* @see SortTest#qsort_desc(int[], int, int)

*/

public void quickSort(int[] data, String sortType) {

if (sortType.equals("asc")) { //正排序,从小排到大

qsort_asc(data, 0, data.length - 1);

} else if (sortType.equals("desc")) { //倒排序,从大排到小

qsort_desc(data, 0, data.length - 1);

} else {

System.out.println("您输入的排序类型错误!");

}

}

/**

* 快速排序的具体实现,排正序

* @param data

* @param low

* @param high

*/

private void qsort_asc(int data[], int low, int high) {

int i, j, x;

if (low < high) { //这个条件用来结束递归

i = low;

j = high;

x = data[i];

while (i < j) {

while (i < j && data[j] > x) {

j--; //从右向左找第一个小于x的数

}

if (i < j) {

data[i] = data[j];

i++;

}

while (i < j && data[i] < x) {

i++; //从左向右找第一个大于x的数

}

if (i < j) {

data[j] = data[i];

j--;

}

}

data[i] = x;

qsort_asc(data, low, i - 1);

qsort_asc(data, i + 1, high);

}

}

/**

* 快速排序的具体实现,排倒序

* @param data

* @param low

* @param high

*/

private void qsort_desc(int data[], int low, int high) {

int i, j, x;

if (low < high) { //这个条件用来结束递归

i = low;

j = high;

x = data[i];

while (i < j) {

while (i < j && data[j] < x) {

j--; //从右向左找第一个小于x的数

}

if (i < j) {

data[i] = data[j];

i++;

}

while (i < j && data[i] > x) {

i++; //从左向右找第一个大于x的数

}

if (i < j) {

data[j] = data[i];

j--;

}

}

data[i] = x;

qsort_desc(data, low, i - 1);

qsort_desc(data, i + 1, high);

}

}

/**

*二分查找特定整数在整型数组中的位置(递归)

*查找线性表必须是有序列表

*@paramdataset

*@paramdata

*@parambeginIndex

*@paramendIndex

*@returnindex

*/

public int binarySearch(int[] dataset, int data, int beginIndex,

int endIndex) {

int midIndex = (beginIndex + endIndex) >>> 1; //相当于mid = (low + high) / 2,但是效率会高些

if (data < dataset[beginIndex] || data > dataset[endIndex]

|| beginIndex > endIndex)

return -1;

if (data < dataset[midIndex]) {

return binarySearch(dataset, data, beginIndex, midIndex - 1);

} else if (data > dataset[midIndex]) {

return binarySearch(dataset, data, midIndex + 1, endIndex);

} else {

return midIndex;

}

}

/**

*二分查找特定整数在整型数组中的位置(非递归)

*查找线性表必须是有序列表

*@paramdataset

*@paramdata

*@returnindex

*/

public int binarySearch(int[] dataset, int data) {

int beginIndex = 0;

int endIndex = dataset.length - 1;

int midIndex = -1;

if (data < dataset[beginIndex] || data > dataset[endIndex]

|| beginIndex > endIndex)

return -1;

while (beginIndex <= endIndex) {

midIndex = (beginIndex + endIndex) >>> 1; //相当于midIndex = (beginIndex + endIndex) / 2,但是效率会高些

if (data < dataset[midIndex]) {

endIndex = midIndex - 1;

} else if (data > dataset[midIndex]) {

beginIndex = midIndex + 1;

} else {

return midIndex;

}

}

return -1;

}

public static void main(String[] args) {

SortTest sortTest = new SortTest();

int[] array = sortTest.createArray();

System.out.println("==========冒泡排序后(正序)==========");

sortTest.bubbleSort(array, "asc");

System.out.println("==========冒泡排序后(倒序)==========");

sortTest.bubbleSort(array, "desc");

array = sortTest.createArray();

System.out.println("==========倒转数组后==========");

sortTest.reverse(array);

array = sortTest.createArray();

System.out.println("==========选择排序后(正序)==========");

sortTest.selectSort(array, "asc");

System.out.println("==========选择排序后(倒序)==========");

sortTest.selectSort(array, "desc");

array = sortTest.createArray();

System.out.println("==========插入排序后(正序)==========");

sortTest.insertSort(array, "asc");

System.out.println("==========插入排序后(倒序)==========");

sortTest.insertSort(array, "desc");

array = sortTest.createArray();

System.out.println("==========快速排序后(正序)==========");

sortTest.quickSort(array, "asc");

sortTest.printArray(array);

System.out.println("==========快速排序后(倒序)==========");

sortTest.quickSort(array, "desc");

sortTest.printArray(array);

System.out.println("==========数组二分查找==========");

System.out.println("您要找的数在第" + sortTest.binarySearch(array, 74)

+ "个位子。(下标从0计算)");

}

}


插入排序
1.直接插入排序

原理:将数组分为无序区和有序区两个区,然后不断将无序区的第一个元素按大小顺序插入到有序区中去,最终将所有无序区元素都移动到有序区完成排序。

要点:设立哨兵,作为临时存储和判断数组边界之用。

实现:

Void InsertSort(Node L[],int length)

{

Int i,j;//分别为有序区和无序区指针

for(i=1;i<length;i++)//逐步扩大有序区

{

j=i+1;

if(L[j]<L[i])

{

L[0]=L[j];//存储待排序元素

While(L[0]<L[i])//查找在有序区中的插入位置,同时移动元素

{

L[i+1]=L[i];//移动

i--;//查找

}

L[i+1]=L[0];//将元素插入

}

i=j-1;//还原有序区指针

}

}

2.希尔排序

原理:又称增量缩小排序。先将序列按增量划分为元素个数相同的若干组,使用直接插入排序法进行排序,然后不断缩小增量直至为1,最后使用直接插入排序完成排序。

要点:增量的选择以及排序最终以1为增量进行排序结束。

实现:

Void shellSort(Node L[],int d)

{

While(d>=1)//直到增量缩小为1

{

Shell(L,d);

d=d/2;//缩小增量

}

}

Void Shell(Node L[],int d)

{

Int i,j;

For(i=d+1;i<length;i++)

{

if(L[i]<L[i-d])

{

L[0]=L[i];

j=i-d;

While(j>0&&L[j]>L[0])

{

L[j+d]=L[j];//移动

j=j-d;//查找

}

L[j+d]=L[0];

}

}

}

交换排序

1.冒泡排序

原理:将序列划分为无序和有序区,不断通过交换较大元素至无序区尾完成排序。

要点:设计交换判断条件,提前结束以排好序的序列循环。

实现:

Void BubbleSort(Node L[])

{

Int i ,j;

Bool ischanged;//设计跳出条件

For(j=n;j<0;j--)

{

ischanged =false;

For(i=0;i<j;i++)

{

If(L[i]>L[i+1])//如果发现较重元素就向后移动

{

Int temp=L[i];

L[i]=L[i+1];

L[i+1]=temp;

Ischanged =true;

}

}

If(!ischanged)//若没有移动则说明序列已经有序,直接跳出

Break;

}

}

2.快速排序

原理:不断寻找一个序列的中点,然后对中点左右的序列递归的进行排序,直至全部序列排序完成,使用了分治的思想。

要点:递归、分治

实现:

选择排序

1.直接选择排序

原理:将序列划分为无序和有序区,寻找无序区中的最小值和无序区的首元素交换,有序区扩大一个,循环最终完成全部排序。

要点:

实现:

Void SelectSort(Node L[])

{

Int i,j,k;//分别为有序区,无序区,无序区最小元素指针

For(i=0;i<length;i++)

{

k=i;

For(j=i+1;j<length;j++)

{

If(L[j]<L[k])

k=j;

}

If(k!=i)//若发现最小元素,则移动到有序区

{

Int temp=L[k];

L[k]=L[i];

L[i]=L[temp];

}

}

}

2.堆排序

原理:利用大根堆或小根堆思想,首先建立堆,然后将堆首与堆尾交换,堆尾之后为有序区。

要点:建堆、交换、调整堆

实现:

Void HeapSort(Node L[])

{

BuildingHeap(L);//建堆(大根堆)

For(int i=n;i>0;i--)//交换

{

Int temp=L[i];

L[i]=L[0];

L[0]=temp;

Heapify(L,0,i);//调整堆

}

}

Void BuildingHeap(Node L[])

{ For(i=length/2 -1;i>0;i--)

Heapify(L,i,length);

}

归并排序

原理:将原序列划分为有序的两个序列,然后利用归并算法进行合并,合并之后即为有序序列。

要点:归并、分治

实现:

Void MergeSort(Node L[],int m,int n)

{

Int k;

If(m<n)

{

K=(m+n)/2;

MergeSort(L,m,k);

MergeSort(L,k+1,n);

Merge(L,m,k,n);

}

}

基数排序

原理:将数字按位数划分出n个关键字,每次针对一个关键字进行排序,然后针对排序后的序列进行下一个关键字的排序,循环至所有关键字都使用过则排序完成。

要点:对关键字的选取,元素分配收集。

实现:

Void RadixSort(Node L[],length,maxradix)

{

Int m,n,k,lsp;

k=1;m=1;

Int temp[10][length-1];

Empty(temp); //清空临时空间

While(k<maxradix) //遍历所有关键字

{

For(int i=0;i<length;i++) //分配过程

{

If(L[i]<m)

Temp[0]
=L[i];

Else

Lsp=(L[i]/m)%10; //确定关键字

Temp[lsp]
=L[i];

n++;

}

CollectElement(L,Temp); //收集

n=0;

m=m*10;

k++;

}

}



http://blog.163.com/jiang-640/blog/static/8640359420092192225711/

可以参考:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: