经典算法总览 【算法设计指南】【C语言实现】【持续更新】

导言:此文章主要用于简要复习常出现于高校算法课上的经典算法,如要详细学习还请查看其它教学

1. 排序

  1.1 归并排序

a.算法思想

        通过分治来排序

        1.将所有元素划分成两组,而后分别递归完成较小问题的排序

        2.对这两个序列表进行某种形式交错 而 合并成一个有序的序列表

b. 简单图示

        1 2 3 4 5 6 7 8 9 → [1 2 3 4 5] + [6 7 8 9]

        暂时只演示右侧的   [6 7 8 9] → [6 7] + [8 9]

        [8 9] → [8] + [9] →合并 sort() → [8] < [9]  ? [8 9] : [9 8]; 接着递归

c. 时间复杂度:        O(n log n)

d.代码示例

注:这里所有的算法的代码实现都不唯一,主要是算法思想

void mergesort(item_type s[], int low, int high)
{
    int middle;    //中间元素下标
    if (low < high) {
        middle = (high - low) / 2 + low; //防止值溢出
        mergesort(s, low, middle);
        mergesort(s, middle+1, high);
        merge(s, low, middle, high);
    }
}

void merge(itme_type s[], int low, int middle, int high)
{
    int i;        // 计数器
    
    item_type l[middle-low+1], r[high-middle];//用于暂时存放待归并元素
    item_type *lb=l, *le=l, *rb=r, *re=r;
    for(i = low; i <= middle; ++i,++le)
        *le = s[i];
    for(; i <= high; ++i,++re)
        *re = s[i];

    // 归并
    i = low;
    while((lb != le) && (rb != re)){
        if(*lb <= *rb)
            s[i++] = *lb++;
        else
            s[i++] = *rb++;
    }
    // 归并剩余序列
    while(lb != le)
        s[i++] = *lb++;
    while(rb != re)
        s[i++] = *rb++;
    
}

    1.2 快速排序

a.算法思想

        通过随机化来排序

        1.从序列中随机选择一项 记为p (枢纽元)

        2.通过 p 将序列分成两队  一对为在序关系下所有排在 p 之前的项;另一对为在序关系下所有排在 p 之后的项

        3.在两队序列中重复 1 和 2 的步骤, 直至序列完全有序

b.简单图示

        黄色背景为 标记p(枢纽元)   蓝色则为有序

        21 3 46 16 31 24 8

        3 8 46 16 31 24 21

        3 8 16 21 46 31 24

        3 8 16 21 24 31 46

        3 8 16 21 24 31 46

c.时间复杂度: O(n log n)

c.代码示例

PS: 如果代码里的注释或图示 难以理解,可直接拿图示的序列手动演示代码的运行过程

void quicksort(item_type s[], int l, int h)
{
    int p; // 划分点下标 即枢纽元 p
    if ((h - l) > 0){
        p = partition(s, l, h);
        quicksort(s, l, p-1);
        quicksort(s, p+1, h);
    }
}

int partition(item_type s[], int l, int h)
{
    int i;            // 计数器
    int p;            // 枢纽元(本程序选择 h 位置为枢纽元)
    int firsthigh;    // 表示枢纽元排序后的位置 可暂时表示枢纽元目前该在的位置
    p = h;
    firsthigh = l;
    for (i = 1; i < h; ++i)
        if (s[i] < s[p]){// 满足条件时 表明s[i] 应该排在枢纽元之前的序列队
            swap(&s[i], &s[firsthigh]);// 将s[i] 放至枢纽元之前的队伍
            ++firsthigh;// 枢纽元位置之前的队伍新增一项 枢纽元位置向后移一位
        }
    swap(&s[p], &s[firsthigh]);
    return firsthigh;
}

      1.3 冒泡排序

a. 算法思想  

        每次比较 i 与 i+1 的元素,如何 i 比 i+1 的元素大或小 就把 i 与 i+1 的元素交换,此为冒泡

b.时间复杂度 : O(n log n)

c.代码示例

void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n-1; i++) {
        for (int j = 0; j < n-i-1; j++) {
            if (arr[j] > arr[j+1]) {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

       1.4  选择排序

a.算法思想

        遍历 n 次无序序列, 每次遍历无序序列找到 最小/最大 的值, 然后将这个 最值 与无序序列的第一个元素交换 (有序序列的后面),与前面的有序序列组成有序序列

b.时间复杂度 :  O(n ^ 2)

c.代码示例

void selectionSort(int arr[], int n) {
    for (int i = 0; i < n-1; i++) {
        int minIndex = i;
        for (int j = i+1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        int temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
}

        1.5 插入排序

a. 算法思想

将无序序列的第一个元素插入到有序序列中合适的位置

b.时间复杂度: O(n ^ 2)

c.代码示例

void insertionSort(int arr[], int n) {
    for (int i = 1; i < n; i++) {
        int key = arr[i];
        int j = i - 1;
        while (j >= 0 && arr[j] > key) {
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = key;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
算法设计与分析》目录: 第一篇引入篇 第1章算法概述1.1用计算机求解问题与算法 1.1.1用计算机求解问题的步骤 1.1.2算法及其要素和特性 1.1.3算法设计及基本方法 1.1.4从算法实现 1.2算法描述 1.2.1算法描述简介 1.2.2算法描述约定 1.2.3一个简单问题的求解过程 1.3现代常用算法概览* 1.3.1压缩算法 1.3.2加密算法 1.3.3人工智能算法 1.3.4并行算法 1.3.5其他实用算法 第2章算法分析基础 2.1算法分析体系及计量 2.1.1算法分析的评价体系 2.1.2算法的时间复杂性 2.1.3算法的空间复杂性 2.1.4NP完全性问题 2.2算法分析实例 2.2.1非递归算法分析 2.2.2递归算法分析 2.2.3提高算法质量 第二篇基础篇 第3章算法基本工具和优化技巧3.1循环与递归 3.1.1循环设计要点 3.1.2递归设计要点 3.1.3循环与递归的比较 3.2算法与数据结构 3.2.1原始信息与处理结果的对应存储 3.2.2数组使信息有序化 3.2.3数组记录状态信息 3.2.4大整数存储及运算 3.2.5构造趣味矩阵 3.3优化算法的基本技巧 3.3.1算术运算的妙用 3.3.2标志量的妙用 3.3.3信息数字化 3.4优化算法的数学模型 3.4.1杨辉三角形的应用 3.4.2最大公约数的应用 3.4.3公倍数的应用 3.4.4斐波那契数列的应用 3.4.5递推关系求解方程 习题 第三篇核心篇 第4章基本的算法策略4.1迭代算法 4.1.1递推法 4.1.2倒推法 4.1.3迭代法解方程 4.2蛮力法 4.2.1枚举法 4.2.2其他范例 4.3分治算法 4.3.1分治算法框架 4.3.2二分法 4.3.3二分法变异 4.3.4其他分治方法 4.4贪婪算法 4.4.1可绝对贪婪问题 4.4.2相对或近似贪婪问题 4.4.3贪婪策略算法设计框架 4.5动态规划 4.5.1认识动态规划 4.5.2动态规划算法设计框架 4.5.3突出阶段性的动态规划应用 4.5.4突出递推的动态规划应用 4.6算法策略间的比较 4.6.1不同算法策略特点小结 4.6.2算法策略间的关联 4.6.3算法策略侧重的问题类型 习题 第5章图的搜索算法 5.1图搜索概述 5.1.1图及其术语 5.1.2图搜索及其术语 5.2广度优先搜索 5.2.1算法框架 5.2.2广度优先搜索的应用 5.3深度优先搜索 5.3.1算法框架 5.3.2深度优先搜索的应用 5.4回溯法 5.4.1认识回溯法 5.4.2回溯法算法框架 5.4.3应用1——基本的回溯搜索 5.4.4应用2——排列及排列树的回溯搜索 5.4.5应用3——最优化问题的回溯搜索 5.5分支限界法 5.5.1分支搜索算法 5.5.2分支限界搜索算法 5.5.3算法框架 5.6 图的搜索算法小结 习题 第四篇应用篇 第6章算法设计实践6.1循环赛日程表 6.2求3个数的最小公倍数 6.3猴子选大王 6.4最大子段和问题 6.5背包问题 6.5.1与利润无关的背包问题 6.5.2与利润有关的背包问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值