排序算法

8/28/2011 9:32:16 PM

本文介绍的排序算法有:冒泡排序,选择排序,插入排序,归并排序,希尔排序,堆排序,快速排序,计数排序,基数排序,桶排序。包括定义描述、排序过程、复杂度和代码实现(如有错误,请指正 Thanks)。

概念:

  • 排序稳定:如果两个数相同,对他们进行的排序结果为他们的相对顺序不变。
  • 原地排序:原地排序就是指不申请多余的空间来进行的排序,就是在原来的排序数据中比较和交换的排序。例如快速排序,堆排序等都是原地排序,合并排序,计数排序等不是原地排序。

冒泡排序 [Bubble Sort]
  依次比较相邻的两个数,将小数放在前面,大数放在后面。
    复杂度:
        最差时间复杂度[O(n^2)],最优时间复杂度[O(n)],平均时间复杂度[O(n^2)],最差空间复杂度[O(n) total, O(1) auxiliary]

   代码:

    C# 版

	 1         public static void BubbleSort(int[] arr)
 2         {
 3             // [flag] {true=> item exchanged; false=> no item exchanged}
 4             bool flag;
 5             int temp;
 6 
 7             for (int i = 0; i < arr.Length - 1; i++)
 8             {
 9                 flag = false;
10                 for (int j = 0; j < arr.Length - i - 1; j++)
11                 {
12                     if (arr[j] > arr[j + 1])
13                     {
14                         temp = arr[j];
15                         arr[j] = arr[j + 1];
16                         arr[j + 1] = temp;
17                         flag = true;
18                     }
19                 }
20                 if (flag == false)
21                 {
22                     break;
23                 }
24             }
25         }

    C 版

	 1 void bubbleSort(int * arr, int n)
 2 {
 3     int i, j, flag, temp;
 4     for (i = 0; i < n - 1; i++)
 5     {
 6         flag = 0;
 7         for (j = 0; j < n - i - 1; j++)
 8         {
 9             if (arr[j] > arr[j + 1])
10             {
11                 temp = arr[j];
12                 arr[j] = arr[j + 1];
13                 arr[j + 1] = temp;
14                 flag = 1;
15             }
16         }
17         if (flag == 0)
18         {
19             break;
20         }
21     }
22 }

选择排序 [Selection Sort]
  每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
    复杂度:
        最差时间复杂度[O(n^2)],最优时间复杂度[O(n^2)],平均时间复杂度[O(n^2)],最差空间复杂度[O(n) total, O(1) auxiliary]

   代码:

    C# 版

	 1         public static void SelectionSort(int[] arr)
 2         {
 3             int minIndex;
 4             int minValue;
 5             int temp;
 6 
 7             for (int i = 0; i < arr.Length - 1; i++)
 8             {
 9                 minValue = arr[i];
10                 minIndex = i;
11                 for (int j = i + 1; j < arr.Length; j++)
12                 {
13                     if (arr[j] < minValue)
14                     {
15                         minValue = arr[j];
16                         minIndex = j;
17                     }
18                 }
19                 if (minIndex != i && minValue != arr[i])
20                 {
21                     temp = arr[i];
22                     arr[i] = arr[minIndex];
23                     arr[minIndex] = temp;
24                 }
25             }
26         }

    C 版

	 1 void selectionSort(int * arr, int n)
 2 {
 3     int minIndex, minValue, temp;
 4     int i, j;
 5 
 6     for (i = 0; i < n -1; i++)
 7     {
 8         minIndex = i;
 9         minValue = arr[i];
10         for (j = i + 1; j < n; j++)
11         {
12             if (arr[j] < minValue)
13             {
14                 minIndex = j;
15                 minValue = arr[j];
16             }
17         }
18         if (minIndex != i && minValue != arr[i])
19         {
20             temp = arr[i];
21             arr[i] = minValue;
22             arr[minIndex] = temp;
23         }
24     }
25 }

插入排序 [Insertion Sort]
  将n个元素的数列分为已有序和无序两个部分,每次处理就是将无序数列的第一个元素与有序数列的元素从后往前逐个进行比较,找出插入位置,将该元素插入到有序数列的合适位置中。
    复杂度:
        最差时间复杂度[O(n^2)],最优时间复杂度[O(n^2)],平均时间复杂度[O(n^2)],最差空间复杂度[O(n) total, O(1) auxiliary]

   代码:

    C# 版

	 1         public static void InsertionSort(int[] arr)
 2         {
 3             int temp;
 4             int j;
 5             for (int i = 1; i < arr.Length; i++)
 6             {
 7                 temp = arr[i];
 8                 for (j = i - 1; j > -1; j--)
 9                 {
10                     if (temp < arr[j])
11                     {
12                         arr[j + 1] = arr[j];
13                     }
14                     else
15                     {
16                         break;
17                     }
18                 }
19                 arr[j + 1] = temp;
20             }
21         }

    C 版

	 1 void insertionSort(int * arr, int n)
 2 {
 3     int i, j, temp;
 4 
 5     for (i = 1; i < n; i++)
 6     {
 7         temp = arr[i];
 8         for (j = i - 1; j > -1; j--)
 9         {
10             if (temp < arr[j])
11             {
12                 arr[j + 1] = arr[j];
13             }
14             else
15             {
16                 break;
17             }
18         }
19         arr[j+1] = temp;
20     }
21 }

归并排序 [Merge Sort]
  将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
    排序过程如下:
      1) 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
      2) 设定两个指针,最初位置分别为两个已经排序序列的起始位置
      3) 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
      4) 重复步骤3直到某一指针达到序列尾
      5) 将另一序列剩下的所有元素直接复制到合并序列尾
    复杂度:
        最差时间复杂度[O(nlogn)],最优时间复杂度[O(n)],平均时间复杂度[O(nlogn)],最差空间复杂度[O(n)]

   代码:

    C# 版

	 1         public static void MergeSort(int[] arr, int start, int end)
 2         {
 3             if (start < end)
 4             {
 5                 int mid = (start + end) / 2;
 6                 MergeSort(arr, start, mid);
 7                 MergeSort(arr, mid + 1, end);
 8                 Merge(arr, start, mid, end);
 9             }
10         }
11         public static void Merge(int[] arr, int start, int mid, int end)
12         {
13             int[] temp = new int[end - start + 1];
14             int i = start;
15             int j = mid + 1;
16             int k = 0;
17             while (i <= mid && j <= end)
18             {
19                 if (arr[i] < arr[j])
20                 {
21                     temp[k++] = arr[i++];
22                 }
23                 else
24                 {
25                     temp[k++] = arr[j++];
26                 }
27             }
28             while (i <= mid)
29             {
30                 temp[k++] = arr[i++];
31             }
32             while (j <= end)
33             {
34                 temp[k++] = arr[j++];
35             }
36             for (k = 0, i = start; k < temp.Length; k++,i++)
37             {
38                 arr[i] = temp[k];
39             }
40         }

    C 版

	 1 void mergeSort(int * arr, int n)
 2 {
 3     if (n > 1)
 4     {
 5         int mid = n / 2;
 6         mergeSort(arr, mid);
 7         mergeSort(arr + mid, n - mid);
 8         merge(arr, n, mid - 1);
 9     }
10 }
11 void merge(int * arr, int n, int mid)
12 {
13     int * temp = malloc(n * sizeof(int));
14     int i = 0;
15     int j = mid + 1;
16     int k = 0;
17 
18     while (i <= mid && j < n)
19     {
20         if (arr[i] < arr[j])
21         {
22             temp[k++] = arr[i++];
23         }
24         else
25         {
26             temp[k++] = arr[j++];
27         }
28     }
29     while (i <= mid)
30     {
31         temp[k++] = arr[i++];
32     }
33     while (j < n)
34     {
35         temp[k++] = arr[j++];
36     }
37 
38     for(k = 0; k < n; k++)
39     {
40         arr[k] = temp[k];
41     }
42     free(temp);
43 }

希尔排序 [Shell Sort]
  希尔排序插入排序的一种,是针对直接插入排序算法的改进,该方法又称缩小增量排序。
    排序过程如下:

      1) 取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组,所有距离为d1的倍数的记录放在同一个组中
      2) 在各组内进行直接插入排序
      3) 取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止

    复杂度:
        最差时间复杂度[O(n^s) 1<s<2, s所选分组],最优时间复杂度[O(nlogn)],平均时间复杂度[O(nlogn)],最差空间复杂度[O(1)]

   代码:

    C# 版

	 1         public static void ShellSort(int[] arr)
 2         {
 3             int d = arr.Length / 2;
 4             int temp, j;
 5 
 6             while (d > 0)
 7             {
 8                 for (int i = 1; i < arr.Length; i++)
 9                 {
10                     temp = arr[i];
11                     for (j = i - d; j >= 0; j -= d)
12                     {
13                         if (arr[j] > temp)
14                         {
15                             arr[j + d] = arr[j];
16                         }
17                         else
18                         {
19                             break;
20                         }
21                     }
22                     arr[j + d] = temp;
23                 }
24                 d /= 2;
25             }
26         }

    C 版

	 1 void shellSort(int * arr, int n)
 2 {
 3     int d = n / 2;
 4     int i, j, temp;
 5 
 6     while (d > 0)
 7     {
 8         for (i = 1; i < n; i++)
 9         {
10             temp = arr[i];
11             for (j = i -d; j >= 0; j -= d)
12             {
13                 if (arr[j] > temp)
14                 {
15                     arr[j + d] = arr[j];
16                 }
17                 else
18                 {
19                     break;
20                 }
21             }
22             arr[j + d] = temp;
23         }
24         d /= 2;
25     }
26 }

堆排序 [Heap Sort]
  堆积排序是指利用堆积树(堆)这种资料结构所设计的一种排序算法,可以利用数组的特点快速定位指定索引的元素。
    排序过程如下:
      1) 建立一个堆H[0..n-1]
      2) 把堆首(最大值)和堆尾互换
      3) 把堆的尺寸缩小1,并调用shift_down(0),目的是把新的数组顶端数据调整到相应位置
      4) 重复步骤2,直到堆的尺寸为1

    复杂度:
        最差时间复杂度[O(nlogn)],最优时间复杂度[O(nlogn)],平均时间复杂度[O(nlogn)],最差空间复杂度[O(n) total, O(1) auxiliary]   

   代码:

    C# 版

	 1         public static void HeapSort(int[] arr)
 2         {
 3             BuildMaxHeap(arr);
 4 
 5             for (int i = arr.Length - 1; i > 0; i--)
 6             {
 7                 Swap(ref arr[0], ref arr[i]); //将堆顶元素和无序区的最后一个元素交换   
 8                 MaxHeaping(arr, 0, i);        //将新的无序区调整为堆
 9             }
10         }
11         /// <summary>   
12         /// 初始化大根堆,由底向上建堆   
13         /// 完全二叉树的基本性质,最底层节点是n/2,所以从arr.Length/2开始   
14         /// </summary>   
15         private static void BuildMaxHeap(int[] arr)
16         {
17             for (int i = arr.Length / 2 - 1; i >= 0; i--)
18             {
19                 MaxHeaping(arr, i, arr.Length);
20             }
21         }
22         /// <summary>   
23         /// 将指定的节点调整为堆 
24         /// </summary>   
25         /// <param name="i">需要调整的节点</param>   
26         /// <param name="heapSize">堆的大小,也指数组中无序区的长度</param>   
27         private static void MaxHeaping(int[] arr, int i, int heapSize)
28         {
29             int left = 2 * i + 1;
30             int right = 2 * i + 2;
31             int large = i;          // 存放大的节点
32 
33             if (left < heapSize && arr[left] > arr[large])
34             {
35                 large = left;
36             }
37             if (right < heapSize && arr[right] > arr[large])
38             {
39                 large = right;
40             }
41             // 如有子节点大于自身就交换,使值大的元素上移
42             if (i != large)
43             {
44                 Swap(ref arr[i], ref arr[large]);
45                 MaxHeaping(arr, i, heapSize);
46             }
47         }
48         private static void Swap(ref int a, ref int b)
49         {
50             int temp = a;
51             a = b;
52             b = temp;
53         }

    C 版

	 1 void heapSort(int * arr, int n)
 2 {
 3     int i;
 4     buildMaxHeap(arr, n);
 5 
 6     for (i = n - 1; i > 0; i--)
 7     {
 8         swap(arr, arr + i);
 9         maxHeaping(arr, 0, i);
10     }
11 }
12 void buildMaxHeap(int * arr, int n)
13 {
14     int i;
15     for (i = n / 2 - 1; i >= 0; i--)
16     {
17         maxHeaping(arr, i, n);
18     }
19 }
20 void maxHeaping(int * arr, int i, int heapsize)
21 {
22     int left = 2 * i + 1;
23     int right = 2 * i + 2;
24     int large = i;
25 
26     if (left < heapsize && arr[left] > arr[large])
27     {
28         large = left;
29     }
30     if (right < heapsize && arr[right] > arr[large])
31     {
32         large = right;
33     }
34     if (i != large)
35     {
36         swap(arr + i, arr + large);
37         maxHeaping(arr, large, heapsize);
38     }
39 }
40 void swap(int * a, int * b)
41 {
42     int temp = *a;
43     *a = *b;
44     *b = temp;
45 }

快速排序 [Quick Sort]
  通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
    排序过程如下:
      1) 设置两个变量i、j,排序开始的时候:i=0,j=n-1
      2) 以第一个数组元素作为关键数据,赋值给key,即 key=A[0]
      3) 从j开始向前搜索,即由后开始向前搜索(j=j-1),找到第一个小于key的值A[j],并与A[i]交换
      4) 从i开始向后搜索,即由前开始向后搜索(i=i+1),找到第一个大于key的A[i],与A[j]交换
      5) 重复第3、4、5步,直到 i=j;(3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i,j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后另循环结束。)

    复杂度:
        最差时间复杂度[O(n^2)],最优时间复杂度[O(nlogn)],平均时间复杂度[O(nlogn)],最差空间复杂度[根据实现方式而定]  

   代码:

    C# 版

	 1         public static void QuickSort(int[] arr, int start, int end)
 2         {
 3             if (end - start <= 0)
 4             {
 5                 return;
 6             }
 7 
 8             int last = start;
 9             int randIndex = new Random().Next(start, end + 1);
10             Swap(ref arr[start], ref arr[randIndex]);
11             for (int i = start + 1; i <= end; i++)
12             {
13                 if (arr[i] < arr[start])
14                 {
15                     Swap(ref arr[++last], ref arr[i]);
16                 }
17             }
18             Swap(ref arr[start], ref arr[last]);
19             QuickSort(arr, start, last - 1);
20             QuickSort(arr, last + 1, end);
21         }
22         private static void Swap(ref int a, ref int b)
23         {
24             int temp = a;
25             a = b;
26             b = temp;
27         }

    C 版

	 1 void swap(int * a, int * b)
 2 {
 3     int temp = *a;
 4     *a = *b;
 5     *b = temp;
 6 }
 7 void quickSort(int * arr, int n)
 8 {
 9     int i, last;
10     if (n <= 1)
11     {
12         return;
13     }
14 
15     swap(arr, arr + rand() % n);
16     last = 0;
17     for (i = 1; i < n; i++)
18     {
19         if (arr[i] < arr[0])
20         {
21             swap(arr + (++last), arr + i);
22         }
23     }
24     swap(arr, arr + last);
25     quickSort(arr, last);
26     quickSort(arr + last + 1, n - last - 1);
27 }

计数排序 [Counting Sort]
   计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。然后根据数组C来将A中的元素排到正确的位置。当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 O(n + k)。计数排序不是比较排序,排序的速度快于任何比较排序算法。
    排序过程如下:
      1) 找出待排序的数组中最大和最小的元素
      2) 统计数组中每个值为i的元素出现的次数,存入数组C的第i项
      3) 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
      4) 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

    复杂度:
        最差时间复杂度[O(n + k)],最优时间复杂度[O(n + k)],平均时间复杂度[O(n + k)],最差空间复杂度[O(n + k)]  (n是排序元素个数,k是元素范围上限)

   代码:

    C# 版

	 1         /*计数排序: 排序arr中元素的值范围是[0,k) */
 2         public static void CountSort(int[] arr, int k)
 3         {
 4             int[] counters = new int[k];
 5             int index = 0;
 6             for (int i = 0; i < arr.Length; i++)
 7             {
 8                 counters[arr[i]]++;
 9             }
10 
11             for (int i = 0; i < k; i++)
12             {
13                 while (counters[i]-- > 0)
14                 {
15                     arr[index++] = i;
16                 }
17             }
18         }

    C 版

	 1 void insertionSort(int * arr, int n)
 2 {
 3     int i, j, temp;
 4 
 5     for (i = 1; i < n; i++)
 6     {
 7         temp = arr[i];
 8         for (j = i - 1; j > -1; j--)
 9         {
10             if (temp < arr[j])
11             {
12                 arr[j + 1] = arr[j];
13             }
14             else
15             {
16                 break;
17             }
18         }
19         arr[j+1] = temp;
20     }
21 }

基数排序 [Radix Sort]
   一种整数排序算法,原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。基数排序的方式可以采用LSD(Least significant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。
    排序过程如下:
      1) 按k1(某位上的数字)排序分组,同一组中记录,关键码k1相等
      2) 再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组
      3) 直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列

    复杂度:
        最差时间复杂度[O(k*n)],最优时间复杂度[O(k*n)],平均时间复杂度[O(k*n)],最差空间复杂度[O(n)]   (n是排序元素个数,k是数字位数)
        代码:

    C# 版

	 1         public static void RadixSort(int[] arr)
 2         {
 3             int maxLength = 1;    //最大数的位数
 4             int tmp, num, i, j;
 5             List<int>[] list = new List<int>[10];
 6 
 7             for (i = 0; i < 10; i++)
 8             {
 9                 list[i] = new List<int>();
10             }
11             for (i = 0; i < arr.Length; i++)
12             {
13                 tmp = arr[i].ToString().Length;
14 
15                 if (tmp > maxLength)
16                 {
17                     maxLength = tmp;
18                 }
19             }
20 
21             for (i = 0; i < maxLength; i++)
22             {
23                 for (j = 0; j < arr.Length; j++)
24                 {
25                     num = arr[j];
26                     tmp = i;
27                     while (tmp > 0)
28                     {
29                         num /= 10;
30                         tmp--;
31                     }
32                     tmp = num % 10;   //第i+1位上的数
33                     list[tmp].Add(arr[j]);
34                 }
35                 tmp = 0;
36                 for (j = 0; j < 10; j++)
37                 {
38                     foreach (int k in list[j])
39                     {
40                         arr[tmp++] = k;
41                     }
42                     list[j].Clear();
43                 }
44             }
45         }

    C 版

	/*动态数组*/
typedef struct
{
    int count;
    int capacity;
    int * data;
}dArray;
int initdArray(dArray * arr, int size)
{
    int ret = 0;
    int initSize = size > 0 ? size : DEFAULTCAP;
    arr->data = (int *)malloc(initSize * sizeof(int));
    if (arr->data != NULL)
    {
        arr->count = 0;
        arr->capacity = initSize;
        ret = 1;
    }
    return ret;
}
int addItemToArr(dArray * arr, int item)
{
    int i;
    if(arr->data == NULL)
    {
        initdArray(arr, DEFAULTCAP);
    }

    if(arr->count == arr->capacity)
    {
        int * ptr = (int*)malloc(arr->count * sizeof(int));
        for (i = 0; i < arr->count; i++)
        {
            ptr[i] = arr->data[i];
        }
        arr->data = (int*)malloc(arr->capacity * 2);
        if (arr->data == NULL)
        {
            free(ptr);
            return 0;
        }
        else
        {
            arr->capacity *= 2;
            for (i = 0; i < arr->count; i++)
            {
                arr->data[i] = ptr[i];
            }
            arr->data[arr->count + 1] = item;
            arr->count++;
            free(ptr);
        }
    }
    else
    {
        arr->data[arr->count++] = item;
    }
    return 1;
}
int getItemFromArr(dArray * arr, int index)
{
    return arr->data[index];
}

/*获得数字n第i位上的数字,从右数,如个位为第一位*/
int getNumAt(int n, int i)
{
    while (i-- > 1)
    {
        n /= 10;
    }
    return n % 10;
}
/*获得数字的长度*/
int getNumLen(int n)
{
    int len = 0;
    while(n)
    {
        n/=10;
        len++;
    }
    return len;
}
void radixSort(int * arr, int n)
{
    int maxlen = 1;
    int tmp, i, j, k;
    dArray * da[10];
    for (i = 0; i < 10; i++)
    {
        da[i] = (dArray *)malloc(sizeof(dArray));
        initdArray(da[i], 10);
    }
    for (i =0; i < n; i++)
    {
        tmp = getNumLen(arr[i]);
        if (tmp > maxlen)
        {
            maxlen = tmp;
        }
    }
    for (i = 0; i < maxlen; i++)
    {
        for (j = 0; j < n; j++)
        {
            addItemToArr(da[getNumAt(arr[j], i + 1)], arr[j]);
        }
        tmp = 0;
        for (j = 0; j < 10; j++)
        {
            for (k = 0; k < da[j]->count; k++)
            {
                arr[tmp++] = getItemFromArr(da[j], k);
            }
            da[j]->count = 0;
        }
    }
}

桶排序 [Bucket Sort]

  桶排序或所谓的箱排序,工作的原理是元素分到有限数量的桶子里。箱排序只适用于关键字取值范围较小的情况,否则所需箱子的数目m太多导致浪费存储空间和计算时间。每個桶子再个别排序(有可能再使用別的排序算法或是以递归方式继续使用桶排序进行排序)。

    排序过程如下:

        1) 设置一定量的阵列作为‘空桶子’
        2) 遍历序列,并把元素一个个放到对应的桶子中
        3) 对每一个不是空的桶子进行排序
        4) 从非空桶子中把元素再放回到原来的序列中

    复杂度:
        时间复杂度[O(n + m)],最差空间复杂度[O(n + m)]  (n个取值范围为1~m的元素,m个桶)

   代码:

    C# 版

	 1         //对值在[0,1)的数进行排序
 2         public static void BucketSort(double[] arr)
 3         {
 4             List<double>[] buckets = new List<double>[10];
 5             int key;
 6             int index = 0;
 7             for (int i = 0; i < buckets.Length; i++)
 8             {
 9                 buckets[i] = new List<double>();
10             }
11 
12             for (int i = 0; i < arr.Length; i++)
13             {
14                 key = (int)(arr[i] * 10);
15                 if (buckets[key].Count == 0)
16                 {
17                     buckets[key].Add(arr[i]);
18                 }
19                 else
20                 {
21                     int j;
22                     for (j = 0; j < buckets[key].Count; j++)
23                     {
24                         if (arr[i] < buckets[key][j])
25                         {
26                             buckets[key].Insert(j, arr[i]);
27                             break;
28                         }
29                     }
30                     if (j == buckets[key].Count)
31                     {
32                         buckets[key].Add(arr[i]);
33                     }
34                 }
35             }
36             
37             for (int i = 0; i < buckets.Length; i++)
38             {
39                 for (int j = 0; j < buckets[i].Count; j++)
40                 {
41                     arr[index++] = buckets[i][j];
42                 }
43             }
44 
45         }

    C 版

	 1 typedef struct Elem
 2 {
 3     double val;
 4     struct Elem * next;
 5 }Elem;
 6 void bucketSort(double * arr, int n)
 7 {
 8     int i, k, key;
 9     Elem * buckets[10];
10     Elem * ptr, * tmp;
11     for (i = 0; i < 10; i++)
12     {
13         buckets[i] = (Elem *)malloc(sizeof(Elem));
14         buckets[i]->next = NULL;
15     }
16     for (i = 0; i < n; i++)
17     {
18         key = (int)(arr[i] * 10);
19         Elem * el = (Elem *)malloc(sizeof(Elem));
20         el->val = arr[i];
21         el->next = NULL;
22         if (buckets[key]->next == NULL)
23         {
24             buckets[key]->next = el;
25         }
26         else
27         {
28             ptr = buckets[key];
29             while(ptr->next != NULL)
30             {
31                 if (arr[i] < ptr->next->val)
32                 {
33                     el->next = ptr->next;
34                     ptr->next = el;
35                     break;
36                 }
37                 ptr = ptr->next;
38             }
39             if(ptr->next == NULL)
40             {
41                 ptr->next = el;
42             }
43         }
44     }
45 
46     for (i = 0, k = 0; i < 10; i++)
47     {
48         ptr = buckets[i]->next;
49         while (ptr != NULL)
50         {
51             arr[k++] = ptr->val;
52             tmp = ptr;
53             ptr = ptr->next;
54             free(tmp);
55         }
56         free(buckets[i]);
57     }
58 }