• 8种基本的排序算法代码(不断更新)


    最近看了两篇不错的博文,是介绍基本的查找和排序算法的,自己也在不断整理,先把代码放网上,参考资料如下:

    Victor Zhang

    SHIroh的专栏

    以上资料中,一个没有代码,另一个使用的JAVA实现,我在这里使用C语言将它们实现了。

    0 头文件声明

    1 #include <stdio.h>
    2 #include <stdlib.h>
    3 typedef int Item;
    4 #define key(A) (A) //返回关键字A
    5 #define less(A, B) ( key(A) < key(B) )   //返回A<B的判断结果
    6 #define exch(A, B) {Item t=A; A=B; B=t;} //交换A和B的值
    7 //如果B<A,则交换两者的值
    8 #define compexch(A, B) { if (less(B, A)) exch(A, B) }

    1 冒泡排序

     1 /** bubble sort
     2   */
     3 void bubble_sort(Item a[], int l, int r)
     4 {
     5     int i, j;
     6     for (i = l; i < r; i++){
     7         for (j = r; j > i; j--){
     8             compexch(a[j-1], a[j]);
     9         }
    10     }
    11 }
    12 void bubble_sort2(Item a[], int l, int r)
    13 {
    14     int i, j, exchanged = 0;
    15     for (i = l; i < r; i++){
    16         for (j = r; j > i; j--){
    17             if (less(a[j], a[j-1])){
    18                 exch(a[j], a[j-1]);
    19                 exchanged = 1;
    20             }
    21         }
    22         if (exchanged != 0) return;
    23     }
    24 }

    2 快速排序

     1 /** quick sort
     2   */
     3 int division(Item a[], int l, int r)
     4 {
     5     int base = a[l];//以最左边的元素为基准
     6     while (l < r){
     7         //从序列右边开始向左边遍历,直到找到小于base的数
     8         while (l < r && a[r] >= base) r--;
     9         a[l] = a[r];//找到比base小的元素,将其放到最左边的位置
    10 
    11         //从序列左边开始向右边遍历,直到找到大于base的数
    12         while (l < r && a[l] <= base) l++;
    13         a[r] = a[l];//找到比base大的元素,将其放到最右边的位置
    14     }
    15     //最后将base放到left指向的位置
    16     a[l] = base;
    17     return l;//返回分割位置
    18 }
    19 
    20 void quick_sort(Item a[], int l, int r)
    21 {
    22     int base;
    23     if (l < r){
    24         //对数组进行分割,取出下次分割的基准编号
    25         base = division(a, l, r);
    26         //对基准左边的元素进行排序
    27         quick_sort(a, l, base - 1);
    28         //对基准右边的元素进行排序
    29         quick_sort(a, base + 1, r);
    30     }
    31 }

    3 插入排序

     1 /** insertion sort
     2   */
     3 void insertion_sort(Item a[], int l, int r)
     4 {
     5     int i, j;
     6     for (i = l + 1; i <= r; i++){
     7         for (j = i; j > l; j--)
     8             compexch(a[j-1], a[j]);
     9     }
    10 }
    11 
    12 void insertion_sort2(Item a[], int l, int r)
    13 {
    14     int i, j, temp;
    15     for (i = l + 1; i <= r; i++){
    16         temp = a[i];//取出第i个元素,跟之前的i-1个数比较
    17         for (j = i - 1; j >= l && temp < a[j]; j--)
    18             a[j+1] = a[j];//将比temp大的数后移
    19         a[j+1] = temp;//将第i个元素插入正确位置
    20     }
    21 }

    4 希尔排序

     1 /** shell sort
     2   */
     3 void shell_sort(Item a[], int l, int r)
     4 {
     5     int i, j, temp, gap = (r - l + 1) / 2;
     6     while (gap >= 1){
     7         for (i = l + gap; i <= r; i++){
     8             temp = a[i];
     9             //对距离为gap的元素进行直接插入排序
    10             for (j = i - gap; j >= l && temp < a[j]; j = j - gap)
    11                 a[j+gap] = a[j];
    12             a[j+gap] = temp;
    13         }
    14         gap = gap / 2;//减小增量
    15     }
    16 }

    5 选择排序

     1 /** selection sort
     2   */
     3 void selection_sort(Item a[], int l, int r)
     4 {
     5     int i, j, index;
     6     for (i = l; i < r; i++){
     7         index = i;
     8         for (j = i + 1; j <= r; j++){
     9             if (less(a[j], a[index])) index = j;
    10         }
    11         exch(a[i], a[index]);
    12     }
    13 }

    6 堆排序

     1 /**
     2   * heap sort
     3   */
     4 void heap_adjust(Item a[], Item parent, int length)
     5 {
     6     Item temp = a[parent];//保存当前父节点
     7     int  child = 2 * parent + 1;//先获得左孩子
     8 
     9     while (child < length){
    10         //如果有右孩子节点,并且右孩子节点的值大于左孩子节点,则选取右孩子节点
    11         if (child+1 < length && a[child] < a[child+1]){
    12             child++;
    13         }
    14         //如果父节点的值已经大于孩子节点的值,则直接结束循环
    15         if (temp >= a[child]) break;
    16         //把孩子节点的值赋给父节点
    17         a[parent] = a[child];
    18         //选取孩子节点的左孩子节点,继续向下筛选
    19         parent = child;
    20         child  = 2 * parent + 1;
    21     }
    22     a[parent] = temp;
    23 }
    24 
    25 void heap_sort(Item a[], int l, int r)
    26 {
    27     int i, length = r - l + 1;
    28     //循环建立初始堆
    29     for (i = length/2; i >= 0; i--){
    30         heap_adjust(a, i, length - 1);
    31     }
    32     //进行n-1次循环,完成排序
    33     for (i = length - 1; i > 0; i--){
    34         exch(a[0], a[i]);//最后一个元素和第一个元素交换
    35         heap_adjust(a, 0, i);//筛选R[0]节点,得到n-1个节点的堆
    36     }
    37 }

    7 归并排序

     1 /** merge sort
     2   */
     3 void merge_opt(Item a[], int low, int mid, int high)
     4 {
     5     int i = low;//i是第一段序列的下标
     6     int j = mid + 1;//j是第二段序列的下标
     7     int k = 0;//k是临时存放合并序列的下标
     8     Item *R2 = (Item *)malloc((high - low + 1)*sizeof(Item));//临时合并序列
     9 
    10     //扫描第一段和第二段序列,直到有一个序列扫描结束
    11     while (i <= mid && j <= high){
    12         // 判断第一段和第二段取出的数哪个更小,将其存入合并序列,并继续向下扫描
    13         if (a[i] <= a[j]){
    14             R2[k] = a[i];
    15             i++; k++;
    16         }else {
    17             R2[k] = a[j];
    18             j++; k++;
    19         }
    20     }
    21     // 若第一段序列还没扫描完,将其全部复制到合并序列
    22     while (i <= mid){
    23         R2[k] = a[i];
    24         i++; k++;
    25     }
    26     // 若第二段序列还没扫描完,将其全部复制到合并序列
    27     while (j <= high){
    28         R2[k] = a[j];
    29         j++; k++;
    30     }
    31     // 将合并序列复制到原始序列中
    32     for (k = 0, i = low; i <= high; i++, k++){
    33         a[i] = R2[k];
    34     }
    35     //最后释放内存
    36     free(R2);
    37 }
    38 
    39 void merge_pass(Item a[], int gap, int length)
    40 {
    41     int i = 0;
    42     //归并gap长度的两个相邻子表
    43     for (i = 0; (i + 2 * gap - 1) < length; i = i + 2 * gap){
    44         merge_opt(a, i, i + gap - 1, i + 2 * gap - 1);
    45     }
    46     //余下两个子表,后者长度小于gap
    47     if (i + gap - 1 < length){
    48         merge_opt(a, i, i + gap - 1, length - 1);
    49     }
    50 }
    51 
    52 void merge_sort(Item a[], int l, int r)
    53 {
    54     int gap, length = r - l + 1;
    55 
    56     for (gap = 1; gap < length; gap = 2 * gap){
    57         merge_pass(a, gap, length);
    58     }
    59 }

    8 基数排序

     1 /** Radix Sort
     2   */
     3 int max_bit(int a[], int n)//辅助函数,求数据的最大位数
     4 {
     5     int digits = 1;//保存最大的位数
     6     int i, p = 10;
     7 
     8     for (i = 0; i < n; i++){
     9         while (a[i] >= p){
    10             p *= 10;
    11             digits++;//位数加1
    12         }
    13     }
    14     return digits;
    15 }
    16 
    17 void radix_sort(int a[], int l, int r)
    18 {
    19     int length = r - l + 1;  //排序数组长度
    20     int digits = max_bit(a, length);//数据最大位数
    21     int i, j, k, radix = 1;
    22     int cnt[10];//计数器
    23     int *tmp =  (int *)malloc(length * sizeof(int));
    24     //进行digits次排序
    25     for (i = 1; i <= digits; i++){
    26         //每次分配前情况计数器
    27         for (j = 0; j < 10; j++){
    28             cnt[j] = 0;
    29         }
    30         //统计每个桶中的记录数
    31         for (j = l; j <= r; j++){
    32             k = (a[j] / radix) % 10;
    33             cnt[k]++;
    34         }
    35         //将tmp中的位置依次分配给每个桶
    36         for (j = 1; j < 10; j++){
    37             cnt[j] = cnt[j-1] + cnt[j];
    38         }
    39         //将所有桶中记录收集到tmp中
    40         for (j = length - 1; j >= 0; j--){
    41             k = (a[j] / radix) % 10;
    42             tmp[cnt[k] - 1] = a[j];
    43             cnt[k]--;
    44         }
    45         //将临时数组中的内容复制到原始数组中
    46         for (j = 0; j < length; j++){
    47             a[j] = tmp[j];
    48         }
    49         radix = 10 * radix;
    50     }
    51     free(tmp);
    52 }

    9 测试代码

     1 int main(int argc, char *argv[])
     2 {
     3 
     4     Item a[10] = {103, 329, 33, 2308, 22222, 35, 4, 7, 6, 30};
     5     //Item a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
     6     int  i;
     7 
     8     radix_sort(a, 0, 9);
     9     for (i = 0; i < 10; i++)
    10         printf("%6d", a[i]);
    11 
    12     return 0;
    13 }
  • 相关阅读:
    Java ArrayList,LinkedList使用
    Vue 使用axios分片上传
    Vue 中Axios 使用
    Vue 自定义组件
    Java IO系统--RandomAccessFile
    Java IO系统--字符流
    Java String类
    静态导入(static import)
    枚举(Enum)
    Java 可变参数
  • 原文地址:https://www.cnblogs.com/xiaomanon/p/4379071.html
Copyright © 2020-2023  润新知