总结:
1.在测试数据的时候从小的数据开始计算。这样容易发现问题。
2.用GDB 调试的时候,快速找到段错误的方法:
start ----> r -----> bt
3.实现规模比较大的函数方法:将大函数写成无数个小函数,不断的小。这样便于调试。思路也比较清晰。
4. 一定要初始化重要的空间或者变量。
基数排序:
1.相比于计数排序的优点在于,减少了辅助空间的开辟。
2.LSD(least significant digital) 适用于位数小的序列
MSD(most significant digital) 适用于位数大的序列
3.思想:
首先按照最低有效位数字进行排序。解决卡片排序问题。这样把各堆卡片收集成一叠。其中0号盒子中的在1号盒子中的前面,后者又在2号盒子中的前面,等等。然后,对整个一叠卡片按次低有效位排序,并把结果同样的合并起来。重复这个过程,直到对所有的d位数字都进行了排序。
4.这个算法的关键点就是按位排序要稳定。
5.伪代码:
RADIX-SORT(A, d)
for i <---- 1 to d
do use a stable sort to sort array A on digit i
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 51
void ran(int *a)
{
int i = 0;
for (i = 0; i < N; i++) {
*(a + i) = rand() % 1000;
}
}
void pri(int *a)
{
int i = 0;
printf("_______________________\n");
for (i = 0; i < N; i++) {
printf("%5d\n", *(a + i));
}
printf("_______________________\n");
}
void cop(int *b, int *a)
{
int i = 0;
for (i = 0; i < N; i++) {
*(b + i) = *(a + i);
}
}
int pow_(int a, int b)
{
int i = 0;
int num = 1;
for (i = 1; i <= b; i++) {
num *= a;
}
return num;
}
/* 求数据的最大位数 */
int maxbit(int a)
{
int i = 1;
int p = 10;
while (a >= p) {
p *= 10;
i++;
}
return i;
}
int max(int *a)
{
int i = 0;
int max = *a;
for (i = 1; i < N; i++) {
if (*(a + i) > max) max = *(a + i);
}
return max;
}
/* use 计数排序保证稳定 */
void count_sort(int *a, int bit)
{
int k = 10, i;
int *c = (int *)malloc(sizeof(int) * 10);
int *b = (int *)malloc(sizeof(int) * N);
memset(c, 0, sizeof(int) * 10); //一定要初始化
memset(b, 0, sizeof(int) * N);
int mod = pow_(10, bit - 1);
for (i = 0; i < N; i++) {
*(c + (*(a + i) / mod % 10)) += 1 ;
}
for (i = 1; i < 10; i++) {
*(c + i) += *(c + i - 1);
}
for (i = N -1; i >= 0; i--) {
*(b + *(c + (*(a + i) / mod % 10)) - 1) = *(a + i);
*(c + (*(a + i) / mod %10)) -= 1;
}
cop(a, b);
free(c);
free(b);
}
void radix_sort(int *a, int d)
{
int i = 1;
for (i = 1; i <= d; i++) {
count_sort(a, i);
}
}
int main()
{
int a[N];
int maxbitn;
ran(a);
maxbitn = maxbit(max(a));
radix_sort(a, maxbitn);
pri(a);
return 0;
}
1.在测试数据的时候从小的数据开始计算。这样容易发现问题。
2.用GDB 调试的时候,快速找到段错误的方法:
start ----> r -----> bt
3.实现规模比较大的函数方法:将大函数写成无数个小函数,不断的小。这样便于调试。思路也比较清晰。
4. 一定要初始化重要的空间或者变量。
基数排序:
1.相比于计数排序的优点在于,减少了辅助空间的开辟。
2.LSD(least significant digital) 适用于位数小的序列
MSD(most significant digital) 适用于位数大的序列
3.思想:
首先按照最低有效位数字进行排序。解决卡片排序问题。这样把各堆卡片收集成一叠。其中0号盒子中的在1号盒子中的前面,后者又在2号盒子中的前面,等等。然后,对整个一叠卡片按次低有效位排序,并把结果同样的合并起来。重复这个过程,直到对所有的d位数字都进行了排序。
4.这个算法的关键点就是按位排序要稳定。
5.伪代码:
RADIX-SORT(A, d)
for i <---- 1 to d
do use a stable sort to sort array A on digit i
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 51
void ran(int *a)
{
int i = 0;
for (i = 0; i < N; i++) {
*(a + i) = rand() % 1000;
}
}
void pri(int *a)
{
int i = 0;
printf("_______________________\n");
for (i = 0; i < N; i++) {
printf("%5d\n", *(a + i));
}
printf("_______________________\n");
}
void cop(int *b, int *a)
{
int i = 0;
for (i = 0; i < N; i++) {
*(b + i) = *(a + i);
}
}
int pow_(int a, int b)
{
int i = 0;
int num = 1;
for (i = 1; i <= b; i++) {
num *= a;
}
return num;
}
/* 求数据的最大位数 */
int maxbit(int a)
{
int i = 1;
int p = 10;
while (a >= p) {
p *= 10;
i++;
}
return i;
}
int max(int *a)
{
int i = 0;
int max = *a;
for (i = 1; i < N; i++) {
if (*(a + i) > max) max = *(a + i);
}
return max;
}
/* use 计数排序保证稳定 */
void count_sort(int *a, int bit)
{
int k = 10, i;
int *c = (int *)malloc(sizeof(int) * 10);
int *b = (int *)malloc(sizeof(int) * N);
memset(c, 0, sizeof(int) * 10); //一定要初始化
memset(b, 0, sizeof(int) * N);
int mod = pow_(10, bit - 1);
for (i = 0; i < N; i++) {
*(c + (*(a + i) / mod % 10)) += 1 ;
}
for (i = 1; i < 10; i++) {
*(c + i) += *(c + i - 1);
}
for (i = N -1; i >= 0; i--) {
*(b + *(c + (*(a + i) / mod % 10)) - 1) = *(a + i);
*(c + (*(a + i) / mod %10)) -= 1;
}
cop(a, b);
free(c);
free(b);
}
void radix_sort(int *a, int d)
{
int i = 1;
for (i = 1; i <= d; i++) {
count_sort(a, i);
}
}
int main()
{
int a[N];
int maxbitn;
ran(a);
maxbitn = maxbit(max(a));
radix_sort(a, maxbitn);
pri(a);
return 0;
}