zoukankan      html  css  js  c++  java
  • 单链表实现基数排序

    基数排序是通过“分配”和“收集”过程来实现排序

    (1)假设有欲排数据序列如下所示:

    73  22  93  43  55  14  28  65  39  81

    首先根据个位数的数值,在遍历数据时将它们各自分配到编号0至9的桶(个位数值与桶号一一对应)中。

    分配结果(逻辑想象)如下图所示:

    分配结束后。接下来将所有桶中所盛数据按照桶号由小到大(桶中由顶至底)依次重新收集串起来,得到如下仍然无序的数据序列:

    81  22  73  93  43  14  55  65  28  39

    接着,再进行一次分配,这次根据十位数值来分配(原理同上),分配结果(逻辑想象)如下图所示:

    分配结束后。接下来再将所有桶中所盛的数据(原理同上)依次重新收集串接起来,得到如下的数据序列:

    14  22  28  39  43  55  65  73  81  93

    观察可以看到,此时原无序数据序列已经排序完毕。如果排序的数据序列有三位数以上的数据,则重复进行以上的动作直至最高位数为止。

    代码 (C语言实现)

      1 #ifndef __SINGLY_LINKED_LIST_H__
      2 #define __SINGLY_LINKED_LIST_H__
      3 
      4 typedef int ElementType;
      5 struct Node;
      6 typedef struct Node* PtrToNode;
      7 typedef PtrToNode List;
      8 typedef PtrToNode Position;
      9 
     10 struct Node
     11 {
     12     ElementType Val;
     13     Position Next;
     14 };
     15 void  CreateList(List*);
     16 void  DeleteList(List);
     17 int  IsEmpty(List);
     18 int  IsLast(Position, List);
     19 Position  Header(List);
     20 Position  First(List);
     21 Position  Advance(Position);
     22 Position  Find(ElementType, List);
     23 ElementType  GetAt(Position);
     24 void  MakeEmpty(List);
     25 void  Delete(ElementType, List);
     26 void  Insert(ElementType, Position, List);
     27 void  InsertFront(ElementType, List);
     28 void  InsertBack(ElementType, List);
     29 
     30 #endif
     31 void  CreateList(List* L)
     32 {
     33     PtrToNode pHeader = (struct Node*)malloc(sizeof(struct Node));
     34     pHeader->Next = NULL;
     35     *L = pHeader;
     36 }
     37 
     38 void  DeleteList(List L)
     39 {
     40     MakeEmpty(L);
     41     free(L);
     42 }
     43 
     44 int  IsEmpty(List L)
     45 {
     46     return L->Next == NULL;
     47 }
     48 
     49 int  IsLast(Position P, List L)
     50 {
     51     return P->Next == NULL;
     52 }
     53 
     54 Position  Header(List L)
     55 {
     56     return L;
     57 }
     58 
     59 Position  First(List L)
     60 {
     61     return L->Next;
     62 }
     63 
     64 Position  Advance(Position P)
     65 {
     66     return P->Next;
     67 }
     68 
     69 Position  Find(ElementType X, List L)
     70 {
     71     Position p = L->Next;
     72     while(p != NULL && p->Val != X)
     73     {
     74         p = p->Next;
     75     }
     76     return p;
     77 }
     78 
     79 ElementType  GetAt(Position P)
     80 {
     81     return P->Val;
     82 }
     83 
     84 void MakeEmpty(List L)
     85 {
     86     Position p, tmp;
     87     p = L->Next;
     88     while(p != NULL)
     89     {
     90         tmp = p->Next;
     91         free(p);
     92         p = NULL;
     93         p = tmp;
     94     }
     95     L->Next = NULL;
     96 }
     97 
     98 void  Delete(ElementType X, List L)
     99 {
    100     Position p, tmp;
    101     p = L;
    102     while(p->Next != NULL && p->Next->Val != X)
    103     {
    104         p = p->Next;
    105     }
    106     if(!IsLast(p, L))
    107     {
    108         tmp = p->Next;
    109         p->Next = tmp->Next;
    110         free(tmp);
    111         tmp = NULL;
    112         // 错误示范:
    113         //free(p->Next);
    114         //p->Next = tmp->Next;
    115     }
    116 }
    117 
    118 void  Insert(ElementType X, Position P, List L)
    119 {
    120     PtrToNode pNode;
    121     pNode = (struct Node*)malloc(sizeof(struct Node));
    122     pNode->Val = X;
    123     pNode->Next = P->Next;
    124     P->Next = pNode;
    125 }
    126 
    127 void  InsertFront(ElementType X, List L)
    128 {
    129     Position pos;
    130     PtrToNode pNode;
    131     pos = L;
    132     pNode = (struct Node*)malloc(sizeof(struct Node));
    133     pNode->Val = X;
    134     pNode->Next = pos->Next;
    135     pos->Next = pNode;
    136 }
    137 
    138 void  InsertBack(ElementType X, List L)
    139 {
    140     Position pos;
    141     PtrToNode pNode;
    142     // move to tail
    143     pos = L;
    144     while(pos->Next != NULL)
    145         pos = pos->Next;
    146     pNode = (struct Node*)malloc(sizeof(struct Node));
    147     pNode->Val = X;
    148     pNode->Next = pos->Next;
    149     pos->Next = pNode;
    150 }

     

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include "SinglyLinkedList.h"
     4 
     5 #define N 10    // 排序的数个数
     6 #define B 10    // 桶数,即基数
     7 #define P 3        // 位数
     8 
     9 void RadixSort(int arr[]);
    10 int GetDigit(int x, int y);
    11 void PrintArray(int arr[], int size);
    12 
    13 int main()
    14 {
    15     int i;
    16     //int arr[N];
    17     int arr[N] = {64, 8, 216, 512, 27, 729, 0, 1, 343, 125};    // 10, 3
    18     //int arr[N] = {64, 8, 216, 512, 125, 729, 0, 729, 343, 125};
    19     //int arr[N] = {12, 58, 37, 64, 52, 36, 99, 63, 18, 9, 20, 88, 47}; // 13, 2
    20 
    21     printf("before sort: ");
    22     PrintArray(arr, N);
    23 
    24     RadixSort(arr);
    25 
    26     printf("after sort: ");
    27     PrintArray(arr, N);
    28 
    29     system("PAUSE");
    30     return 0;
    31 }
    32 
    33 void RadixSort(int arr[])
    34 {
    35     int i, j, k, digit;
    36     Position pos;
    37     List bucket[B];
    38 
    39     // 创建桶
    40     for(i=0; i<B; ++i)
    41         CreateList(&bucket[i]);      // 从低位到高位循环每一位数字
    42     for(i=0; i<P; ++i)
    43     {
    44         // 将桶置空
    45         for(j=0; j<B; ++j)
    46             MakeEmpty(bucket[j]);  // 根据当前位上的数字,将之放入对应桶中。并注意顺序(后进的放在后面)
    47         for(j=0; j<N; ++j)
    48         {
    49             digit = GetDigit(arr[j], i);
    50             InsertBack(arr[j], bucket[digit]);
    51         }
    52         k = 0;
    53         // 将每趟排序后的结果存回arr
    54         for(j=0; j<B; ++j)
    55         {
    56             pos = First(bucket[j]);
    57             while(pos != NULL)
    58             {
    59                 arr[k++] = pos->Val;
    60                 pos = pos->Next;
    61             }
    62         }
    63     }
    64 
    65     for(i=0; i<B; ++i)
    66         DeleteList(bucket[i]);
    67 }
    68 
    69 
    70 // 取整数x的倒数第y位数字,y从0开始
    71 int GetDigit(int x, int y)
    72 {
    73     int i, t = 1;
    74     for(i=0; i<=y; ++i)
    75             t *= 10;
    76     return (x % t) / (t / 10);
    77 }
    78 
    79 
    80 void PrintArray(int arr[], int size)
    81 {
    82     int i;
    83     for(i=0; i<size; ++i)
    84     {
    85         printf("%d ", arr[i]);
    86     }
    87     printf("
    ");
    88 }

     参考1

     参考2

     

  • 相关阅读:
    串匹配模式中的BF算法和KMP算法
    “隐藏与显示”的多种方法实现
    原生js实现tooltip提示框的效果
    心向旋转巧得木马 峰回路转偶得时钟
    jQuery 之 验证表单
    Java代码添加背景音乐
    svg动画 之 我的自制太阳系
    java_22 Map接口
    java_22.1 Map 的应用
    java_18 Collection接口
  • 原文地址:https://www.cnblogs.com/xjtuchenpeng/p/4979253.html
Copyright © 2011-2022 走看看