数据结构与算法从零玩转C语言程序设计

12-C语言排序算法

2018-09-04  本文已影响419人  极客江南

计数排序(Counting Sort)

int main()
{
    // 待排序数组
    int nums[5] = {3, 1, 2, 0, 3};
    // 用于排序数组
    int newNums[4] = {0};
    // 计算待排序数组长度
    int len = sizeof(nums) / sizeof(nums[0]);
    // 遍历待排序数组
    for(int i = 0; i < len; i++){
        // 取出待排序数组当前值
        int index = nums[i];
        // 将待排序数组当前值作为排序数组索引
        // 将用于排序数组对应索引原有值+1
        newNums[index] = newNums[index] +1;
    }
    
    // 计算待排序数组长度
    int len2 = sizeof(newNums) / sizeof(newNums[0]);
    // 输出排序数组索引, 就是排序之后结果
    for(int i = 0; i < len2; i++){
        for(int j = 0; j < newNums[i]; j++){
            printf("%i\n", i);
        }
    }
    /*
    // 计算待排序数组长度
    int len2 = sizeof(newNums) / sizeof(newNums[0]);
    // 还原排序结果到待排序数组
    for(int i = 0; i < len2; i++){
        int index = 0;
        for(int i = 0; i < len; i++){
            for(int j = 0; j < newNums[i]; j++){
                nums[index++] = i;
            }
        }
    }
    */
    return 0;
}

选择排序


// 选择排序
void selectSort(int numbers[], int length) {
    
    // 外循环为什么要-1?
    // 最后一位不用比较, 也没有下一位和它比较, 否则会出现错误访问
    for (int i = 0; i < length; i++) {
        for (int j = i; j < length - 1; j++) {
            // 1.用当前元素和后续所有元素比较
            if (numbers[i] < numbers[j + 1]) {
                //  2.一旦发现小于就交换位置
                swapEle(numbers, i, j + 1);
            }
        }
    }
}
// 交换两个元素的值, i/j需要交换的索引
void swapEle(int array[], int i, int j) {
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

冒泡排序

// 冒泡排序
void bubbleSort(int numbers[], int length) {
    for (int i = 0; i < length; i++) {
        // -1防止`角标越界`: 访问到了不属于自己的索引
        for (int j = 0; j < length - i - 1; j++) {
           //  1.用当前元素和相邻元素比较
            if (numbers[j] < numbers[j + 1]) {
                //  2.一旦发现小于就交换位置
                swapEle(numbers, j, j + 1);
            }
        }
    }
}
// 交换两个元素的值, i/j需要交换的索引
void swapEle(int array[], int i, int j) {
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

插入排序

int main()
{
    // 待排序数组
    int nums[5] = {3, 1, 2, 0, 3};
    // 0.计算待排序数组长度
    int len = sizeof(nums) / sizeof(nums[0]);

    //  1.从第一个元素开始依次取出所有用于比较元素
    for (int i = 1; i < len; i++)
    {
        // 2.取出用于比较元素
        int temp = nums[i];
        int j = i;
        while(j > 0){
            // 3.判断元素是否小于前一个元素
            if(temp < nums[j - 1]){
                // 4.让前一个元素向后移动一位
                nums[j] = nums[j - 1];
            }else{
                break;
            }
            j--;
        }
        // 5.将元素插入到空出来的位置
        nums[j] = temp;
    }
}
int main()
{
    // 待排序数组
    int nums[5] = {3, 1, 2, 0, 3};
    // 0.计算待排序数组长度
    int len = sizeof(nums) / sizeof(nums[0]);

    //  1.从第一个元素开始依次取出所有用于比较元素
    for (int i = 1; i < len; i++)
    {
        // 2.遍历取出前面元素进行比较
        for(int j = i; j > 0; j--)
        {
            // 3.如果前面一个元素大于当前元素,就交换位置
            if(nums[j-1] > nums[j]){
                int temp = nums[j];
                nums[j] = nums[j - 1];
                nums[j - 1] = temp;
            }else{
                break;
            }
        }
    }
}

希尔排序

int main()
{
    // 待排序数组
    int nums[5] = {3, 1, 2, 0, 3};
    // 0.计算待排序数组长度
    int len = sizeof(nums) / sizeof(nums[0]);

// 2.计算步长
    int gap = len / 2;
    do{
        //  1.从第一个元素开始依次取出所有用于比较元素
        for (int i = gap; i < len; i++)
        {
            // 2.遍历取出前面元素进行比较
            int j = i;
            while((j - gap) >= 0)
            {
                printf("%i > %i\n", nums[j - gap], nums[j]);
                // 3.如果前面一个元素大于当前元素,就交换位置
                if(nums[j - gap] > nums[j]){
                    int temp = nums[j];
                    nums[j] = nums[j - gap];
                    nums[j - gap] = temp;
                }else{
                    break;
                }
                j--;
            }
        }
        // 每个小数组排序完成, 重新计算步长
        gap = gap / 2;
    }while(gap >= 1);
}

江哥提示:
对于初学者而言, 排序算法一次不易于学习太多, 咋们先来5个玩一玩, 后续继续讲解其它5个


折半查找


int findKey(int values[], int length, int key) {
    // 定义一个变量记录最小索引
    int min = 0;
    // 定义一个变量记录最大索引
    int max = length - 1;
    // 定义一个变量记录中间索引
    int mid = (min + max) * 0.5;
    
    while (min <= max) {
        // 如果mid对应的值 大于 key, 那么max要变小
        if (values[mid] > key) {
            max = mid - 1;
            // 如果mid对应的值 小于 key, 那么min要变
        }else if (values[mid] < key) {
            min = mid + 1;
        }else {
            return mid;
        }
        // 修改完min/max之后, 重新计算mid的值
        mid = (min + max) * 0.5;
    }
    return -1;
}

进制转换(查表法)

#include <stdio.h>
void toBinary(int num)
{
    total(num, 1, 1);
}
void toOct(int num)
{
    total(num, 7, 3);
}
void toHex(int num)
{
    total(num, 15, 4);
}

void total(int num , int base, int offset)
{
    //    1.定义表用于查询结果
    char cs[] = {
        '0', '1', '2', '3', '4', '5',
        '6', '7', '8', '9', 'a', 'b',
        'c', 'd', 'e', 'f'
    };
    //    2.定义保存结果的数组
    char rs[32];
    //    计算最大的角标位置
    int length = sizeof(rs)/sizeof(char);
    int pos = length;//8

    while (num != 0) {
        int index = num & base;
        rs[--pos] = cs[index];
        num = num >> offset;
    }

    for (int i = pos; i < length; i++) {
        printf("%c", rs[i]);
    }
    printf("\n");
}
int main()
{
    toBinary(9);
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读