• C++数据结构和算法 01


    首先开篇先来一道入门题:

    给了一个接口定义,尝试实现:  Memmove

    1. void *memmove(void *dest,const void *src,size_t n)
    2. {
    3. }

    这个函数呢是想从内存中一块内容从src拷贝到dest ,固定长度是n,实现代码

    要注意常见的陷阱有以下几种(是时候重温一下C++的课程了/(ㄒoㄒ)/~~)

    1. 内存重叠的处理
    2. 临时变量太对或者没有安全释放
    3. 没有测试内存越界
    4. 指针操作不熟悉 

    好啦下面是有问题的代码 :

    1. void *memmove(void *dest,const void *src,size_t n)
    2. {
    3. char *p1=dest;
    4. char *p2=src;
    5. while(*p2!=\0)
    6. *p1++=*p2++;
    7. return p1;
    8. }

    万事开头慢嘛,开始会很慢,先分析一下存在的问题:

    内存重叠问题

    (1) 有可能dest就是在src内存之内,那就导致了内存重叠;

    (2)有可能dest在src前面,非内存重叠;

    (3) 有可能dest在src后面,非内存重叠;

    所以说,其实我一开始想到的就是dest 在 src 后面,然后通过循环赋值 把src内容赋值给dest,这的确是思维漏洞了,想的不够全面,的确有可能src的三个值里面就有dest 

    学习一下正确的写法:

    1. void *memmove (void *dest,const void *src,size_t n)
    2. {
    3. char *p1=dest;
    4. const char *p2=src;//对应上
    5. //判断了 p1 和 p2 的位置关系
    6. if(p2//出现了内存重叠情况
    7. {
    8. p2+=n;//把p2支到了n+1的位置
    9. p1+=n;//把p1支到了不在p2内的位置
    10. while(n--!=0)//通过倒过来的方法,从后往前赋值
    11. *--p1=*--p2;
    12. }
    13. else//没有出现重叠情况
    14. {
    15. while(n--!=0)//正常顺序赋值
    16. *p1++=*p2++;
    17. }
    18. return p1;
    19. }

     大概意思我画了个草图,方便我各个理解。


    接下来呢记录一下一个二叉树的点

                    4                                                           4   

                 /     \                                                      /     \

             2            7                  =====>>>            7       2

            /  \          /  \                                             / \       / \

         1     3      6    9                                         9   6    3   1

    如图,就是把上面二叉树的顺序调换

    1. /**
    2. * Definition for a binary tree node.
    3. * struct TreeNode{
    4. * int val;
    5. * TreeNode *left;
    6. * TreeNode *right;
    7. * TreeNode(int x),left(NULL),right(NULL){}
    8. * };
    9. */
    10. class Solution {
    11. public:
    12. TreeNode* invertTree(TreeNode* root) {
    13. if (root == NULL)
    14. return NULL;
    15. TreeNode* tmpNode=root->left;
    16. root->left = invertTree(root->right);
    17. root->right = invertTree(tmpNode);
    18. return root;
    19. }
    20. };

    分析代码:注释部分就是定义一个树,判断树是否为空,不为空就把树左子树和右子树互换

    有时候其实多看几遍我也能看懂代码的大概意思,我是觉得在精不在多,这么多次都没坚持下去就是因为总觉的得刷量,但是质量没有保障,忘了就跟没学过一样。加油吧


    排列组合模板

    1、全排列:就是所有排列顺序都显示出来 n个字符应该是有n!个结果

    1. void Permutation(char* pStr, char* pBegin)
    2. {
    3. assert(pStr && pBegin);
    4. if (*pBegin == '\0')
    5. {
    6. printf("%s\n", pStr);
    7. }
    8. else
    9. {
    10. for (char* pCh = pBegin; *pCh != '\0'; pCh++)
    11. {
    12. swap(*pBegin, *pCh);
    13. Permutation(pStr, pBegin + 1);
    14. swap(*pBegin, *pCh);
    15. }
    16. }
    17. }

    2、组合:对于每个元素,可以有选和不选两个状态。 


    这是我在b站上听的课,感兴趣的可以去看看,一起学习~


    《《 数组和字符串 》》

    入门题:有这么一个 strStr C语言的一个函数库,想在source里面寻找target,如果找到了返回第一次出现的位置,如果不存在返回 -1 。这是一个字符串匹配的问题。

    首先介绍暴力算法(Brute-Force)

    顺序的遍历母串,然后将每个字符作为匹配的起始字符,判断是否匹配子串。

    时间复杂度是 O(m*n)

    1. char* strStr(const char* str, const char* target)
    2. {
    3. if (!*target) //判断target是否为空
    4. {
    5. return str;
    6. }
    7. char* p1 = (char*)str;
    8. while (*p1)
    9. {
    10. char* p1Begin = p1, * p2 = (char*)target;
    11. while (*p1 && *p2 && *p1 == *p2)
    12. {
    13. p1++;
    14. p2++;
    15. }
    16. if (!*p2)
    17. {
    18. return p1Begin;//临时存储p1位置
    19. }
    20. p1 = p1Begin + 1;
    21. }
    22. return NULL;
    23. }

  • 相关阅读:
    vue3-hash-calendar,一款基于vue3.x开发的移动端日期时间选择组件
    日常问题:MySQL排序字段数据相同不能分页问题
    C Primer Plus(6) 中文版 第6章 C控制语句:循环 6.12 使用函数返回值的循环示例
    机器学习 - 常见问题与解决方案
    Mysql的B+树高度计算
    视频怎么压缩?视频过大这样压缩变小
    Vue脚手架初始化&脚手架结构分析
    Linux文件系统和软硬连接
    DTI-ALPS处理笔记
    matlab图像的增强
  • 原文地址:https://blog.csdn.net/GiGi_Princess/article/details/126815087