桶排序(BucketSort)

1 桶排序核心思想是 根据数据规模n划分 m个相同大小的区间 (每个区间为一个桶,桶可理解为容器)

2 每个桶存储区间内的元素(区间为半开区间 例如[0,10) 或者 [200,300) )

3 将n个元素按照规定范围分布到各个桶中去

4 对每个桶中的元素进行排序,排序方法可根据需要,选择快速排序,或者归并排序,或者插入排序

5 依次从每个桶中取出元素,按顺序放入到最初的输出序列中(相当于把所有的桶中的元素合并到一起)

6 桶可以通过数据结构链表实现

7 基于一个前提,待排序的n个元素大小介于0~k 之间的整数  或者是(0, 1)的浮点数也可(算法导论8.4的例子) 

8 桶排序的时间代价,假设有m个桶,则每个桶的元素为n/m

 当辅助函数为冒泡排序O(n2)  ,桶排序为 O(n)+mO((n/m)2)

   当辅助函数为快速排序时O(nlgn),  桶排序为 O(n)+mO(n/m log(n/m)) 

9 通常桶越多,执行效率越快,即省时间,但是桶越多,空间消耗就越大,是一种通过空间换时间的方式

注意:代码前部分为辅助代码

   辅助类:链表Link

辅助函数:冒泡排序BubbleSort

  1 #include <iostream>

  2 #include <crtdbg.h>

  3 #include <cstring>

  4 using namespace std;

  5 

  6 typedef int DataType;

  7 //建立链表

  8 class Link

  9 {

 10 private:

 11     struct Node

 12     {

 13         DataType data;

 14         Node *next;

 15     };

 16     Node *head; //哨兵位

 17 public:

 18     Link()

 19     {

 20         Init();

 21     }

 22     ~Link()

 23     {

 24         Delete();

 25     }

 26     void Init()

 27     {

 28         head = new Node;

 29         head->next = NULL;

 30     }

 31     void Delete()

 32     {

 33         for (Node *p = head; p != NULL;)

 34         {

 35             Node *pTemp = p->next;

 36             delete p;

 37             p = pTemp;

 38         }

 39         head = NULL;

 40     }

 41     void Print()

 42     {

 43         for (Node *p = head->next; p != NULL; p = p->next)

 44         {

 45             cout << p->data << endl;

 46         }

 47     }

 48     //顺序插入 考虑两种情况 1.空表 2.当插入值是最大值的时候

 49     void SortInsert(DataType data)

 50     {

 51         Node *p = head;

 52         do 

 53         {

 54             if (p->next == NULL || p->next->data > data)

 55             {

 56                 Node *pNew = new Node;

 57                 pNew->data = data;

 58                 pNew->next = p->next;

 59                 p->next = pNew;

 60 

 61                 return;

 62             }

 63             p = p->next;

 64         } while (true);

 65     }

 66     //尾插法直接插入

 67     void Insert(DataType data)

 68     {

 69         Node *p = head;

 70         while(p->next != NULL)

 71         {

 72             p = p->next;

 73         }

 74 

 75         Node *pNew = new Node;

 76         pNew->data = data;

 77         pNew->next = NULL;

 78         p->next = pNew;

 79     }

 80     bool Empty()

 81     {

 82         return head->next == NULL;

 83     }

 84     //去掉首结点并返回首结点的值

 85     int ExtractDate()

 86     {

 87         if (! Empty())

 88         {

 89             DataType data = head->next->data;

 90             Node *p = head->next;

 91             Node *pFirst = p->next;

 92 

 93             delete p;

 94             p = NULL;

 95 

 96             head->next = pFirst; 

 97             return data;

 98         }

 99         return -1;

100     }

101 };

102 //冒泡排序

103 void BubbleSort(int *a, int size)

104 {

105     for(int i=0; i<size; ++i)

106     {

107         for (int j=0; j<size-1-i; ++j)

108         {

109             if (a[j] > a[j+1])

110             {

111                 int tmp = a[j];

112                 a[j] = a[j+1];

113                 a[j+1] = tmp;

114             }

115         }

116     }

117 }

118 //基于一个前提:待排序的n个元素大小是介于 0~k 之间的整数

119 //array待排序数组,result辅助数组存储排序结果,k为允许的最大整数

120 void BucketSort(int array[], int result[], int size, int k)

121 {

122     Link *Bucket = new Link[5];   //建立桶     

123     int sectionSize = k/5;        //记录区间大小

124     int index=0;            //记录区间下标

125 

126     //方法1:一般步骤

127     //按照范围把array中的每个值放入相应的桶中

128     for(int i=0; i<size; ++i)

129     {

130         index = array[i]/sectionSize;

131         Bucket[index].Insert(array[i]); //为保证稳定性,链表使用了尾插法插入

132     }

133     //遍历每个桶,取出桶中的元素,放入辅助数组result,并排序

134     int j=0 , m=0;

135     for (int i=0; i<5; ++i) 

136     {

137         m = j; //记录已排好序的数组元素大小

138         while(!Bucket[i].Empty())

139         {

140             result[j++] = Bucket[i].ExtractDate();    

141         }

142 

143         //可根据实际情况选择快速排序,堆排序等,此处简单起见选择冒泡排序

144         BubbleSort(result+m, j-m);

145     }

146      

147     //方法2:使用链表特性,在插入链表的同时排序

148     //for(int i=0; i<size; ++i)

149     //{

150     //    index = array[i]/sectionSize;

151     //    Bucket[index].SortInsert(array[i]);

152     //}

153     //int j=0;

154     //for(int i=0; i<5; ++i)

155     //{

156     //    while(!Bucket[i].Empty())

157     //    {

158     //        result[j++] = Bucket[i].ExtractDate();    

159     //    }

160     //}

161 

162     delete [] Bucket;

163 }

164 

165 void main()

166 {

167     //检测是否有内存泄露 需要加头文件#include <crtdbg.h>

168     _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

169 

170     int Array[10] = {2, 6, 5, 3, 0, 7, 2, 3, 0, 3};

171     int Result[10] = {0};

172 

173     BucketSort(Array, Result, sizeof(Array)/sizeof(Array[0]), 10);

174 

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

176     {

177         cout << Result[i] << "\n";

178     }

179 

180     system("pause");

181 }

 

(转载请注明作者和出处^_*  Seven++ http://www.cnblogs.com/sevenPP/  )

你可能感兴趣的:(sort)