自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

程序员的规则

成长的历史

  • 博客(144)
  • 收藏
  • 关注

原创 八大排序之基数排序

基数排序又称桶排序,是按位数一位一位的分类好,放在单独的空间中,再进行排序,排序好之后再将所有的数据收集出来。然后再按下一位重新进行分类,再排序,再收集...直到序列中的最大数的位数到达最高位时,最后一次收集,就直接有序了。概念可能比较难理解,上图解:解释:数是哪个位上的,就是为了使这个范围内的数有序。例如:432 456 478这三个数,第一次就是为了使2 6 8这三个个位数有序,第二次是为了32 56 78这三个十位数有序,第三次就是为了使432 456 478这三个百位数有序。代码实.

2022-04-07 23:24:51 292

原创 八大排序之堆排序

堆排序引论:既然是堆排序,那么我们必须知道堆是什么?堆是具有以下性质的完全二叉树:每个节点的值都大于等于左右孩子节点的值,称为大顶堆;或者每个节点的值都小于或等于其左右孩子节点的值,称为小顶堆。根据堆的定义可知,根节点一定是堆中所有节点最大(小)着。较大(小)的节点靠近节点(但也不绝对)如图:如果将上图按照层次遍历存入数组,那么一定满足下面的关系:堆排序算法堆排序就是利用堆(假设利用大顶堆)进行排序的方法。它的基本思想是,将待排序的序列构造成一个大顶堆。此时,整个序列的最大.

2022-04-07 20:55:13 214

原创 八大排序之归并排序

归并排序引论:归并排序就是利用归并的思想实现的排序方法。它的原理是假设初始序列含有n个记录,则可以看成是有n个有序的子序列,没个子序列的长度为1,然后两两归并,得到[n/2]([x]表示不小于x的最小整数)个长度为2或1的有序子序列;然后两两归并,....,如此重复,直至得到一个长度为n的有序序列为止,这种方法称为2路归并排序。一般我们最先想到的是采用递归的方法解决,那么我们需要直到递推和回归,递推的是划分之后的乱序数列,回归的是有序的数列,递推的过程可以看做一棵正的二叉树,回归的.

2022-04-07 17:01:54 1182

原创 八大排序之希尔排序

希尔排序引论:简单来说就是,希尔排序其实是一个特殊的直接插入排序,特殊之处在于为了降低时间复杂度,我们需要在调用直接插入排序之前,先想办法让它基本有序,而这个办法就是将相距某个增量的记录组成一个子序列,相当于多次调用直接插入排序,每一次的增量都保持互素,并且最后一个增量一定为1,为1才能保证其完全有序。如果了解直接插入排序的话,希尔排序就是很容易理解的(前两次调用直接插入排序是为了让数列基本有序,最后一次和直接插入排序完全一致):void Shell(int* ar, int n, i

2022-04-06 23:22:00 183

原创 八大排序之直接插入排序

描述:直接插入排序的基本操作是将一个数插入到已经排序好的有序表中,从而得到一个新的、记录数增1的有序表。插入排序与选择排序还是比较相似的,不同的是,这个排序不是从右半部分选择最小的,而是直接选择右边第一个数据,除此之外,还有一点不同的是,选择排序左半部分不用去排序,只需找到右边最小元素最后交换即可有序,而插入排序则不同,它每次都要比较,直到找到合适位置。图解:代码实现:int InsertSort(int *ar,int n){ assert(ar != NULL); if (ar

2022-04-06 22:19:08 149

原创 八大排序之选择排序

选择排序概述:上边的概念可能还能比较难理解,没关系,接下来我们会详细讲解:对于选择排序,就是每次选择一个较小的数来排序。我们可以将一个杂乱的数列分成两部分,左半部分是有序的数,右半部分是无序的数,我们需要做的就是从右边无序的数列中找出一个最小的树放在左半部分中。因为每次都是从右半部分选出最小的数来移到左半部分,所以左半部分始终是有序的。图解:上图只是便于理解,在具体实现时,我们不可能再重新开辟一块空间来存放有序序列。那么如何解决呢?我们希望的是数列从左向右开始慢慢有序,那么我们如果要将找出的

2022-04-06 19:04:47 338

原创 冒泡排序详解

概述:冒泡排序是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果范旭则交换,直到没有反序的记录为止。冒泡的实现在细节上可以有很多种变化,我们通过具体的代码,来理解冒泡排序的思想。先来看比较容易理解的一段:void BubbleSort(int* ar, int n){ int count=0; assert(ar != NULL); for (int i = 0; i < n-1; i++) { for (int j = 0; j < n - i - 1; j

2022-04-04 00:38:16 424

原创 从上到下打印二叉树

题目描述:请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推本题还是在二叉树层次遍历的基础上改动过来的,有需要的话,可以先看看我前两篇的题解,有助于理解此题:https://blog.csdn.net/qq_54669536/article/details/123940163https://blog.csdn.net/qq_54669536/article/details/123941309思路

2022-04-03 20:56:57 1580

原创 从上到下打印二叉树

题目描述:从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。此题是在层次遍历的基础上改动过来的,有需要的话,可以先看看我的上一篇题解:https://blog.csdn.net/qq_54669536/article/details/123940163题目解析:此遍历方式本质还是二叉树层次遍历,只是加了一个条件,将每一层分开输出。其实实现方式是很简单的,我们只需要在while循环内层再加一个循环,因为我们入队是一层一层入队的,当入完一层后,我们记录当前队列中的元素个数s

2022-04-03 18:09:27 909

原创 从上到下打印二叉树

题目描述:从上到下打印二叉树的每个节点并且同一层的节点按照从左到右的顺序打印题目解析:此题目即是我们平常所说的二叉树的层次遍历。不论哪种遍历方式,都是要从根节点开始的,而此时的层次遍历,我们既要从头结点开始,也要首先打印出来,后续的也是。所以,层次遍历遵从了这样一个特点,先进的先出,后进的后出,这个时候我们使用队列是最方便的。定义一个队列,若根节点不为空,则进行入队,判断队列为不为空,不为空的时候出队并进行打印,判断出队的节点它的左右孩子是否为空(注意一定是先左后右),不为空时继续入队,然后出队下一个节

2022-04-03 17:01:54 647

原创 旋转数组的最小元素

题目描述:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。 注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。思路

2022-04-03 12:27:43 519

原创 二维数组中的查找

题目描述:在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。思路解析:对于这个题,我们可能第一时间想到的就是使用暴力遍历整个矩阵,这个办法是可行的,但是此方法似乎没有用到矩阵从左到右,从上到下的特点,显然不是最优解法,时间复杂度达到了O(NM)。回想我们在一维递增数组中查找元素的时候,也是通过二分查找来提高效率的,不会从头到尾的遍历。那么对于这个二维数组,我们也需要利

2022-04-03 11:06:32 319

原创 0~n-1中缺失的数字

题目描述:一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。思路描述:对于这道题,我们首先想到的就是暴力破解,遍历一边找出来,但是如果数组很大的话,这样的时间复杂度就太高了。注意题目:递增排序数组,并且数组元素全部唯一且是从0开始的,那么数组元素应该等于对应的下标。既然是这样。我们可以直接找到数组中间节点,判断nums[mid]==mid;如果相等,说明前半部分没有缺失元素,去后半部分找,

2022-03-31 23:00:21 714

原创 在排序数组中查找数字

题目描述:统计一个数字在排序数组中出现的次数方法一思路描述:看到这个题目,我们首先想到的就是利用map直接统计次数,思路非常简单,将数组元素全部存到map中,然后直接统计即可:代码实现:class Solution {public: int search(vector<int>& nums, int target) { unordered_map<int,int>s; for(int num:nums)

2022-03-31 22:31:55 459

原创 数组中的重复数字

题目描述:在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字方法一思路描述:最容易想到的就是暴力求解了,但是又没有更简单的方法呢?我们可以利用map,将数组中的元素添加到map中,在添加时先判断此键值是否为真,若为真,说明元素已经存在,此元素是重复的;若不为真,则说明是第一次添加,设置为真。代码实现:class Solution {public: in

2022-03-31 21:28:58 529

原创 select/poll/epoll的区别

1.用户态将文件描述符传入内核的方式select:创建3个文件描述符集并拷贝到内核中,分别监听读、写、异常动作。这里受到单个进程可以打开的fd数量限制,默认是1024个。poll:将传入的struct pollfd结构体数组拷贝到内核中进行监听。epoll:执行epoll_create会在内核的告诉cache区建立一棵红黑树以及就绪链表(该链表只存储已经就绪的文件描述符)。接着用户执行epoll_ctl函数添加文件描述符会在红黑树上增加相应的节点。2.内核态检测文件描述符读写状态的方式s

2022-03-31 18:01:27 1409

原创 左旋转字符串

题目描述:字符串的左旋转是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如:输入字符串“abcdefg”和数字2,该函数将返回左旋转两位得到的结果"cdefgab"方法一解题思路:既然是字符串,我们就可以利用string类型的成员函数。将字符串的前n个字符尾插到字符串的后边,然后再将前边的前n个字符删除掉,就可以了。代码实现:string reverseLeftWords(string s, int n) { for(int i=0;i

2022-03-30 17:03:32 497

原创 复杂链表的复制

题目描述:请实现copyRandomList函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个next指针指向下一个节点,还有一个random指针指向链表中的任意节点或者NULL;题目疑问:链表复制明明可以直接遍历链表,创建新节点实现,这里的random指针起什么作用?题目解疑:如题目所述,这里需要的是复杂链表的复制,这里的random指针起什么作用并不重要,重要的是我们如何将随机指针正确的复制过去。思路:...

2022-03-30 16:18:18 395

原创 *链表逆转

题目描述:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点//头结点定义 struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} };思路:对于链表逆置,最常用的方法就是一直头插了和反转节点的next了,这两种方法又分别有两种情况,链表有头结点和链表无头结点。一直头插:一直头插就是将原有链表的节点从前到后一个一个拆下来再重新

2022-03-30 14:45:57 942

原创 定义栈的数据结构并得到最小元素

题目描述:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)栈的数据结构都是很简单的,此题的主要难点就是如何在时间复杂度为O(1)的情况下找到最小元素思路:要想只调用一次函数就得到最小元素,那么最小元素必须是栈顶元素。要达到这个目的,只能是在元素入栈时就比较之后再存放,将最小的较小的元素放在栈顶(注意:这里说的是较小,而不是最小)。对于一个栈来说,随着入栈元素的增加,不一定能将最小的元素放在栈顶,如图:

2022-03-28 17:27:32 1611

原创 两个栈实现一个队列

题目描述:用两个栈实现一个队列,分别完成在队列尾部插入整数和在队头删除整数的功能。(若队列中没有元素,删除函数返回-1)解题思路:众所周知,栈的基本特点是先入后出,队列的基本特点是先入先出。那么两个栈所需要完成的任务就是一个先入,一个先出,那么如何实现这个功能呢?我们将栈1功能定为入队,栈2功能定为出队,此时要让先入栈1的先出,我们可以把栈1的所有元素都入到栈2中(顺序反过来),再将栈2的第一个元素出栈(相当于栈1的尾部元素==队列的头部元素),最后将栈2的元素重新入栈到栈1中。如此即可完成队列的头部出队,

2022-03-28 16:21:56 458

原创 银行转账带来的死锁问题

如果只是单纯的进行两个账户之间的转账,那么久很容易导致死锁问题std::mutex mxA;std::mutex mxB;int countA = 1000;int countB = 1000;void thread_fun1(int money){ std::unique_lock<std::mutex>lcA(mxA); cout << "线程1获得了A账户的锁" << endl; if (countA > money) { cout

2022-03-24 21:51:52 383

原创 多线程编程

int funa(int n, int& x){ for (int i = 0; i <= n; i ++ ) { cout << "thread funa" << endl; std::this_thread::sleep_for(std::chrono::microseconds(100)); } x = n; cout << "thread funa_end()" << endl; return n;}...

2022-03-23 20:41:50 513

原创 生产者和消费者

不能精准的唤醒,必须通过while循环控制不可改变为if语句

2022-03-23 20:06:05 414

原创 STL链表

#ifndef ZJH_LIST_H#define ZJH_LISH_H#include<iostream>using namespace std;namespace yhp{ template<class T> void Swap(T& a, T& b) { T tmp = a; a = b; b = tmp; } template<class _Ty> class list { protected: struc

2022-03-21 20:27:33 472

原创 红黑树详解

typedef enum{RED=0,BLACK=1}ColorType;typedef int KeyType;typedef struct rb_node{ rb_node* leftchild; rb_node* parent; rb_node* rightchild; ColorType color; KeyType key;}rb_node,&RBTree;rb_node* Buynode(){ rb_node* s = (rb_node*)malloc(si.

2022-03-21 20:17:50 62

原创 半同步半异步线程池

阿帕奇Web服务器nginx链接池问题:线程上下文的切换?当任务队列为空时,线程是什么状态?

2022-03-21 20:09:59 166

原创 空间配置器

namespace zjh{ //如果是if0,当内存不足时,就抛出异常 //如果是if1,当内存不足时,就显示内存不足#if 0#include<new>#define _THROW_BAD_ALLOC throw std::bad_alloc#elif !defined(_THROW_BAD_ALLOC)#define _THROW_BAD_ALLOC std::cerr<<"out of memory"<<std::endl;exit(1)#en.

2022-03-21 20:06:52 78

原创 二叉搜索树

每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同左子树(如果存在)上所有节点的关键码都小于根节点的关键码左子树(如果存在)上所有节点的关键码都小于根节点的关键码...

2022-03-21 20:05:58 644

原创 关于二叉树的常问问题

节点定义typedef char ElemType;typedef struct BtNode{ ElemType data; struct BtNode* leftchild; struct BtNode* rightchild;}BtNode,*BinaryTree;如何判断二叉树是满二叉树描述:对于满二叉树来说,它的每一层节点的个数都是2的幂次方个,那么我们就可以利用这个特点,使用两个队列,在每一次入队完之后,判断一次队中的个数是否达到了当前的2的幂次方个,如果达到了,则继

2022-03-20 21:22:48 1157

原创 二叉树详解

树的介绍树的定义树是由n(n>=0)个节点组成的有限集合。如果n=0,称为空树;如果n>0,则:有一个特定的称之为根(root)的节点,它只有直接后继,但没有直接前驱;除根以外的其它节点划分为m(m>=0)个互不相交的有限集合,每个集合又是一棵树,并且称之为根的子树,没棵子树的根节点有且只有一个直接前驱,但可以有0个或多个直接后继树的性质:节点的度:一个节点含有的子树的个数称为该节点的度; 树的度:一棵树中,最大的节点的度称为树的度(这里不一定是根节点,如

2022-03-20 19:45:24 5039 1

原创 AVL树详解

目录AVL树定义节点定义购买节点插入节点平衡化旋转左旋右旋改变平衡因子单旋与双旋的判断先左后右型:当为左单旋时图解:当为双旋时(E的balance为1时)图解:当为双旋时(E的balance为-1时)图解:先右后左型:当为单旋时:当为双旋时(D的balance为-1时)图解:当为双旋时(D的balance为1时)图解:AVL树定义一颗AVL树或者是孔数,或者是具有以下性质的二叉搜索树:它的左子树和...

2022-03-16 20:02:26 1356

原创 线程安全-栈

当入栈获得锁时,必须从用户态转移到内核态,锁住互斥锁,再到达用户态继续向下运行。在入栈时,出栈函数由于获取不到锁,就会阻塞,直到入栈函数执行完释放锁之后才能在内核态获得锁,再转移到用户态继续执行。同步:同步的意思是函数执行有顺序,A执行完之后才能执行B,B执行完之后才能执行C,以此类推。而不是简单的理解为同步就是同时执行异步:异步指的是在同一时间内,A B C函数可能同时执行,没有固定的顺序,互相不影响。完整代码://栈空异常类型,主要为栈空做准备struct empty_stack :std:.

2022-02-27 22:55:41 822

原创 CAS原子操作

void pop() { std::lock_guard<std::mutex>lock(mtx); if (base != NULL) { StackNode* q = base; base = q->next; &(q->data)->~T(); Freenode(q); cursize -= 1; } }改为原子操作:完整代码:#include<iostream>#include&l..

2022-02-27 22:52:45 342

原创 算法-最长递增子序列

int rob(vector<int>& nums){ int n = nums.size(); if (n == 0)return 0; if (n == 1)return 1; vector<int>dp(n, 0); for (int i = 0; i < n; ++i) { dp[i] = 1; for (int j = 0; j < i; ++j) { if (nums[i] > nums[j]) { .

2022-02-27 22:47:00 71

原创 算法-打家劫舍

int rob(vector<int>& nums){ int n = nums.size(); if (n <= 0)return 0; if (n == 1)return nums[1]; vector<int>dp(n,0); dp[0] = nums[1]; dp[1] = max(nums[1],nums[0]); for(int i = 2; i < n; i++) { dp[i] = max(dp[i - 1], dp[i -.

2022-02-27 22:01:40 102

原创 算法-求具有最大和的连续子序列

dp[i]相当于前i-1家总和

2022-02-27 21:16:37 325

原创 智能指针weak_ptr(二)-循环引用问题

template<class _Ty>class RefCnt{public: _Ty* _Ptr;//指向Obj std::atomic_int _User;//对应shared_ptr std::atomic_int _Weaks;//对应weak_ptrpublic: RefCnt(_Ty*p):mptr(p),_User(1),_Weaks(1){} ~RefCnt(){} void _Incref() { _User += 1; } void _Incwr

2022-02-25 13:01:19 517

原创 智能指针weak_ptr(一)

直接上代码//单个删除器template<class _Ty>class MyDeletor{public: MyDeletor() {} void operator()(_Ty* ptr)const { if (ptr != NULL) { delete ptr; } }};//数组删除器template<class _Ty>class MyDeletor<_Ty[]>{public: MyDeletor() = def

2022-02-25 13:00:51 376

原创 动态规划-最长公共子序列

寻求两个字符串的最长公共子序列假设:A={X1,X2,X3,X4,X5,X6…Xm};B={Y1,Y2,Y3,Y4,Y5…Yn};算法思想:如果Xm=Yn,那么最长公共子序列的最后一个元素一定就是Xm/Yn如果Xm!=Yn&&Xm!=Zkc[m][n]=(m==0||n==0)?0m>1,n>1c[m][n]=(xm==yn)?c[m-1][n-1]+1c[m][n]=(Xm!=Yn)?Max(c[m-1][n],c[m][n-1])...

2022-02-25 00:18:19 412

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除