[关闭]
@Dubyoo 2014-06-20T21:44:44.000000Z 字数 3067 阅读 2222

2014-06-11 六种排序方式 sort.c


1. 选择排序 select_sort

  1. void select_sort(int* arr, int len)
  2. {
  3. int i, j;
  4. for(i = 0; i < len - 1; i++)
  5. {
  6. int min = i;
  7. for(j = i + 1; j < len; j++)
  8. {
  9. if(arr[min] > arr[j])
  10. min = j;
  11. }
  12. if(min != i)
  13. _swap(&arr[i], &arr[min]);
  14. }
  15. }

2. 插入排序 insert_sort

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

3. 冒泡排序 bubble_sort

  1. void bubble_sort(int* arr, int len)
  2. {
  3. int i, j;
  4. for(i = 0; i < len - 1; i++)
  5. {
  6. for(j = len; j > i; j--)
  7. {
  8. if(arr[j] < arr[j - 1])
  9. _swap(&arr[j], &arr[j - 1]);
  10. }
  11. }
  12. }

4. 快速排序 quick_sort

  1. /*
  2. * 分治Partition,
  3. * 两个下标分别从首尾向中间扫描
  4. */
  5. int partition(int* arr, int len)
  6. {
  7. int left = 0, right = len - 1;
  8. int pivot = arr[left]; //以当前表中第一个元素为枢轴值进行划分
  9. while(left < right) //结束条件
  10. {
  11. while(left < right && arr[right] >= pivot)
  12. right--;
  13. arr[left] = arr[right]; //比枢轴值小的元素移动到左端
  14. while(left < right && arr[left] < pivot)
  15. left++;
  16. arr[right] = arr[left]; //比枢轴值大的元素移动到右端
  17. }
  18. arr[left] = pivot; //枢轴元素放到最终位置
  19. return left; //返回该位置
  20. }
  21. void quick_sort(int* arr, int len)
  22. {
  23. if(len > 0)
  24. {
  25. int part = partition(arr, len);
  26. quick_sort(arr, part);
  27. quick_sort(arr + part + 1, len - part - 1);
  28. }
  29. }

5. 堆排序 heap_sort

  1. /*
  2. * 本函数功能是:根据数组 arr 构建大根堆
  3. * arr 是待调整的堆数组,
  4. * i 是待调整的数组元素的位置,
  5. * len 是数组的长度
  6. */
  7. void heap_adjust(int* arr, int i, int len)
  8. {
  9. int child;
  10. for(; 2*i+1 < len; i = child)
  11. {
  12. child=2*i+1; //子结点的位置=2*(父结点位置)+1
  13. if(child < len-1 && arr[child+1] > arr[child]) //得到子结点中较大的结点
  14. ++child;
  15. if(arr[i] < arr[child])
  16. //如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点
  17. _swap(&arr[i], &arr[child]);
  18. else //否则,不需要再向下调整,直接跳出
  19. break;
  20. }
  21. }
  22. /*
  23. * 堆排序算法
  24. */
  25. void heap_sort(int* arr, int len)
  26. {
  27. //调整序列的前半部分元素,调整完之后第一个元素是序列的最大的元素
  28. //length/2-1是最后一个非叶节点,此处"/"为整除
  29. for(int i = len/2-1; i >= 0; --i)
  30. heap_adjust(arr, i, len);
  31. //从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
  32. for(int i = len-1; i > 0; --i)
  33. {
  34. //把第一个元素和当前的最后一个元素交换,
  35. //保证当前的最后一个位置的元素都是在现在的这个序列之中最大的
  36. _swap(&arr[0], &arr[i]);
  37. //不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值
  38. heap_adjust(arr, 0, i);
  39. }
  40. }

6. 归并排序

  1. /*
  2. * 归并:
  3. * 将有两个有序数组
  4. * a[first ... mid],
  5. * a[mid ... last]
  6. * 合并
  7. */
  8. void mergearray(int arr[], int first, int mid, int last, int temp[])
  9. {
  10. int i = first, j = mid + 1;
  11. int k = 0;
  12. while (i <= mid && j <= last)
  13. //两边都有元素时,进行比较,将较小元素存入临时数组
  14. {
  15. if (arr[i] <= arr[j])
  16. temp[k++] = arr[i++];
  17. else
  18. temp[k++] = arr[j++];
  19. }
  20. while (i <= mid) //剩下一个数组可能还存在多余元素,直接存入临时数组
  21. temp[k++] = arr[i++];
  22. while (j <= last) //同上
  23. temp[k++] = arr[j++];
  24. for (i = 0; i < k; i++) //将临时数组中的有序数赋给原数组
  25. arr[first + i] = temp[i];
  26. }
  27. /*
  28. * 归并排序算法
  29. */
  30. void mergesort(int arr[], int first, int last, int temp[])
  31. {
  32. if (first < last)
  33. {
  34. int mid = (first + last) / 2;
  35. mergesort(arr, first, mid, temp); //左边有序
  36. mergesort(arr, mid + 1, last, temp); //右边有序
  37. mergearray(arr, first, mid, last, temp); //再将两个有序数列合并
  38. }
  39. }
  40. bool merge_sort(int arr[], int len)
  41. {
  42. int *p = new int[len];
  43. //在此处开辟临时数组,
  44. //防止在算法中多次开辟和删除临时数组造成的开销(耗时)过大
  45. if (p == NULL)
  46. return false;
  47. mergesort(arr, 0, len - 1, p);
  48. delete[] p;
  49. return true;
  50. }

50个随机数测试

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #define SIZE 50
  5. void _swap(int* a, int* b)
  6. {
  7. int tmp = *a;
  8. *a = *b;
  9. *b = tmp;
  10. }
  11. void print(int* arr, int len)
  12. {
  13. int i;
  14. for(i = 0; i < len; i++)
  15. {
  16. printf("%4d", arr[i]);
  17. if((i + 1)%10 == 0)
  18. printf("\n");
  19. }
  20. }
  21. int main()
  22. {
  23. srand(time(NULL));
  24. int arr[SIZE];
  25. int i;
  26. for(i = 0; i < SIZE; i++)
  27. {
  28. arr[i] = rand()%1000;
  29. }
  30. printf("before sort:\n");
  31. print(arr, SIZE);
  32. printf("\n");
  33. //select_sort(arr, SIZE);
  34. //insert_sort(arr, SIZE);
  35. //bubble_sort(arr, SIZE);
  36. //quick_sort(arr, SIZE);
  37. //heap_sort(arr, SIZE);
  38. merge_sort(arr, SIZE);
  39. printf("after sort:\n");
  40. print(arr, SIZE);
  41. return 0;
  42. }

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注