手撕合集

冒泡
void bubbleSort(vector<int>& arr)
{
    int n = arr.size();
    while(n != 0)
    {
        for(int i = 1; i < n; i++)
        {
            if(arr[i] < arr[i - 1])
                swap(arr[i], arr[i - 1]);
        }
        n--;
    }
}

选择排序
void selectionSort(vector<int>& arr)
{
    int n = arr.size();
    for(int i = 0; i < n; i++)
    {
        int minindex = i;
        //每一轮找出最小的和i位置上的交换
        for(int j = i + 1; j < n; j++)
        {
            if(arr[j] < arr[minindex])
                minindex = j;
        }
        swap(arr[i], arr[minindex]);
    }
}

插入排序
void insertionSort(vector<int>& arr)
{
    int n = arr.size();
    for(int i = 1; i < n; i++)
    {
        //将每一个元素放入到前面已经排好序序列的正确位置
        for(int j = i - 1; i >= 0; j--)
        {
            if(arr[i] < arr[j])
                swap(arr[i], arr[j]);
        }
    }
}

插入排序改进
void insertionSort_advance(vector<int>& arr)
{
    int n = arr.size();
    for(int i = 1; i < n; i++)
    {
        int t = arr[i];
        int j; // j保存元素e应该插入的位置
        for (j = i; j > 0 && arr[j-1] > t; j--)
            arr[j] = arr[j-1];
        arr[j] = t;
    }
}

1.快排
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;

vector<int> generateArray(int maxsize, int maxvalue, int minvalue)
{
    srand(time(NULL));
    int size = rand() % (maxsize + 1);
    //cout << size << endl;
    vector<int> arr;
    arr.reserve(size);
    for (int i = 0; i < size; i++)
    {
        arr.push_back(rand() % (maxvalue - minvalue + 1) + minvalue);
    }
    return arr;
}

vector<int> copyArray(const vector<int>& arr)
{
    vector<int> hh;
    hh.reserve(arr.size());
    for(int i = 0; i < arr.size(); i++)
        hh.push_back(arr[i]);
    return hh;
}

bool isEqual(const vector<int>& first, const vector<int>& second)
{
    if(first.size() != second.size())
        return false;
    else
    {
        for(int i = 0; i < first.size(); i++)
        {
            if(first[i] != second[i])
                return false;
        }
    }
    return true;
}

pair<int, int> __partition(vector<int>& arr, int L, int R)
{
    int T = arr[rand() % (R - L + 1) + L];
    int less = L - 1;
    int more = R + 1;
    int cur = L;
    while(cur < more)
    {
        if(arr[cur] < T)
            swap(arr[++less], arr[cur++]);
        else if(arr[cur] > T)
            swap(arr[--more], arr[cur]);
        else
            cur++;
    }
    pair<int, int> hh(less, more);
    return hh;
}

void __quicksort(vector<int>& arr, int L, int R)
{
    if(L >= R)
        return;
    pair<int, int> hh = __partition(arr, L, R);
    __quicksort(arr, L, hh.first);
    __quicksort(arr, hh.second, R);
}

void quickSort(vector<int>& arr)
{
    srand(time(NULL));
    __quicksort(arr, 0, arr.size() - 1);
}

int main()
{
    int testtime = 500000;
    int size = 300;
    int maxvalue = 10000;
    int minvalue = 20;
    bool succeed = true;
    for(int i = 0; i < testtime; i++)
    {
        vector<int> a = generateArray(size, maxvalue, minvalue);
        vector<int> b = copyArray(a);
        quickSort(a);
        sort(b.begin(), b.end());
        if(!isEqual(a, b))
        {
            succeed = false;
            for(auto c:a)
                cout << c << " ";
            cout << endl;
            break;
        }
    }
    if(succeed == false)
        cout << "You Lose!" << endl;
    else
        cout << "You Win! Congradulations!" << endl;
    return 0;
}

2.堆排
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;

vector<int> generateArray(int maxsize, int maxvalue, int minvalue)
{
    srand(time(NULL));
    int size = rand() % (maxsize + 1);
    //cout << size << endl;
    vector<int> arr;
    arr.reserve(size);
    for (int i = 0; i < size; i++)
    {
        arr.push_back(rand() % (maxvalue - minvalue + 1) + minvalue);
    }
    return arr;
}

vector<int> copyArray(const vector<int>& arr)
{
    vector<int> hh;
    hh.reserve(arr.size());
    for(int i = 0; i < arr.size(); i++)
        hh.push_back(arr[i]);
    return hh;
}

bool isEqual(const vector<int>& first, const vector<int>& second)
{
    if(first.size() != second.size())
        return false;
    else
    {
        for(int i = 0; i < first.size(); i++)
        {
            if(first[i] != second[i])
                return false;
        }
    }
    return true;
}

void heapInsert(vector<int>& arr, int index)
{
    while(arr[index] > arr[(index - 1) / 2])
    {
        swap(arr[index], arr[(index - 1) / 2]);
        index = (index - 1) / 2;
    }
}

void heapify(vector<int>&arr, int index, int heapsize)
{
    int left = index * 2 + 1;
    while (left < heapsize)
    {
        int largerindex = left + 1 < heapsize && arr[left + 1] > arr[left]
                ? left + 1 : left;
        largerindex = arr[largerindex] > arr[index] ? largerindex :index;
        if(largerindex == index)
            break;
        swap(arr[largerindex], arr[index]);
        index = largerindex;
        left = index * 2 + 1;
    }
    
}

void heapSort(vector<int>& arr)
{
    for(int i = 0; i < arr.size(); i++)
        heapInsert(arr, i);
    
    int heapSize = arr.size();
    swap(arr[0], arr[--heapSize]);
    while(heapSize > 0)
    {
        heapify(arr, 0, heapSize);
        swap(arr[0], arr[--heapSize]);
    }
}

int main()
{
    int testtime = 500000;
    int size = 300;
    int maxvalue = 10000;
    int minvalue = 20;
    bool succeed = true;
    for(int i = 0; i < testtime; i++)
    {
        vector<int> a = generateArray(size, maxvalue, minvalue);
        vector<int> b = copyArray(a);
        heapSort(a);
        sort(b.begin(), b.end());
        if(!isEqual(a, b))
        {
            succeed = false;
            for(auto c:a)
                cout << c << " ";
            cout << endl;
            break;
        }
    }
    if(succeed == false)
        cout << "You Lose!" << endl;
    else
        cout << "You Win! Congradulations!" << endl;
    return 0;
}

一个使用示例:

/*
有一笔钱100万
有一堆项目,分别需要投资20 90 100 130 120 200 160 260
收益分别是 5 20 30 30 35 20 60 90
总共能做5个项目
请问一个项目一个项目的做(也就是能够拿到这个项目的收益)
求收益最大化
*/
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <functional>

using namespace std;

class CostAndProfile
{
public:
    CostAndProfile(int cost, int profile)
    {
        this->cost = cost;
        this->profile = profile;
    }
    int cost;
    int profile;
    
};

class compare1
{
public:
    bool operator()( CostAndProfile left, CostAndProfile right) const
    {
        return left.cost > right.cost;
    }
};

class compare2
{
public:
    bool operator()( CostAndProfile left, CostAndProfile right) const
    {
        return left.profile < right.profile;
    }
};



//利用大根堆和小根堆
int mostMoney(const vector<CostAndProfile>& hh, int maxtime, int summoney)
{
    //构建花费的小根堆
    priority_queue<CostAndProfile, vector<CostAndProfile>, compare1> mincostheap;
    for(auto a:hh)
        mincostheap.push(a);
    //构建收益的大根堆
    priority_queue<CostAndProfile, vector<CostAndProfile>, compare2> maxprofileheap;
    for(int i = 0; i < maxtime; i++)
    {
        while(!mincostheap.empty() && mincostheap.top().cost <= summoney)
        {
            maxprofileheap.push(mincostheap.top());
            mincostheap.pop();
        }
        if(maxprofileheap.empty())
            return summoney;
        summoney += maxprofileheap.top().profile;
        maxprofileheap.pop();
    }
    return summoney;
}

int main()
{
    vector<CostAndProfile> hh;
    hh.push_back(CostAndProfile(20, 5));
    hh.push_back(CostAndProfile(90, 20));
    hh.push_back(CostAndProfile(100, 30));
    hh.push_back(CostAndProfile(130, 30));
    hh.push_back(CostAndProfile(120, 35));
    hh.push_back(CostAndProfile(200, 20));
    hh.push_back(CostAndProfile(160, 60));
    hh.push_back(CostAndProfile(260, 90));
    int maxtime = 5;
    int summoney = 100;
    cout << mostMoney(hh, maxtime, summoney) - summoney << endl;
    return 0;
}

3.归并排
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;

vector<int> generateArray(int maxsize, int maxvalue, int minvalue)
{
    srand(time(NULL));
    int size = rand() % (maxsize + 1);
    //cout << size << endl;
    vector<int> arr;
    arr.reserve(size);
    for (int i = 0; i < size; i++)
    {
        arr.push_back(rand() % (maxvalue - minvalue + 1) + minvalue);
    }
    return arr;
}

vector<int> copyArray(const vector<int>& arr)
{
    vector<int> hh;
    hh.reserve(arr.size());
    for(int i = 0; i < arr.size(); i++)
        hh.push_back(arr[i]);
    return hh;
}

bool isEqual(const vector<int>& first, const vector<int>& second)
{
    if(first.size() != second.size())
        return false;
    else
    {
        for(int i = 0; i < first.size(); i++)
        {
            if(first[i] != second[i])
                return false;
        }
    }
    return true;
}

void merge(vector<int>& arr, int l, int mid, int r)
{
    vector<int> tmp;
    tmp.reserve(r - l + 1);
    int i = l, j = mid+1;
    while(i <= mid && j <= r)
        tmp.push_back(arr[i] < arr[j] ? arr[i++] : arr[j++]);
    while(i <= mid)
        tmp.push_back(arr[i++]);
    while(j <= r)
        tmp.push_back(arr[j++]);
    for(int i = 0; i < tmp.size(); i++)
        arr[l + i] = tmp[i];
}

void _mergeSort(vector<int>& arr, int l, int r)
{
    if(l == r)
        return;
    int mid = (l + r) / 2;
    _mergeSort(arr, l, mid);
    _mergeSort(arr, mid + 1, r);
    merge(arr, l, mid, r);
}

void mergeSort(vector<int>& arr)
{
    _mergeSort(arr, 0, arr.size() - 1);
}

int main()
{
    int testtime = 500000;
    int size = 300;
    int maxvalue = 10000;
    int minvalue = 20;
    bool succeed = true;
    for(int i = 0; i < testtime; i++)
    {
        vector<int> a = generateArray(size, maxvalue, minvalue);
        vector<int> b = copyArray(a);
        mergeSort(a);
        sort(b.begin(), b.end());
        if(!isEqual(a, b))
        {
            succeed = false;
            for(auto c:a)
                cout << c << " ";
            cout << endl;
            break;
        }
    }
    if(succeed == false)
        cout << "You Lose!" << endl;
    else
        cout << "You Win! Congradulations!" << endl;
    return 0;
}

4.树的遍历,递归非递归
#include <iostream>

using namespace std;

struct TreeNode
{
    TreeNode* left = NULL;
    TreeNode* right = NULL;
    int value;
};

TreeNode* createAtree()
{
    //随便创建一个
    TreeNode* root = new TreeNode;
    root->value = 1;
    root->left = new TreeNode;
    root->left->value = 2;
    root->right = new TreeNode;
    root->right->value = 3;
    root->left->left = new TreeNode;
    root->left->left->value = 4;
    root->right->left = new TreeNode;
    root->right->left->value = 5;
    root->right->right = new TreeNode;
    root->right->right->value = 6;
    return root;
}

void pretraverse(TreeNode* root)
{
    //根结点-左孩子-右孩子
    if(root == NULL)
        return;
    cout << root->value << " ";
    pretraverse(root->left);
    pretraverse(root->right);
}

void intraverse(TreeNode* root)
{
    //左孩子-根结点-右孩子
    if(root == NULL)
        return;
    intraverse(root->left);
    cout << root->value << " ";
    intraverse(root->right);
}

void posttraverse(TreeNode* root)
{
    //左孩子-右孩子-跟结点
    if(root == NULL)
        return;
    posttraverse(root->left);
    posttraverse(root->right);
    cout << root->value << " ";
}

int main()
{
    TreeNode* root = createAtree();
    cout << "preorder: ";
    pretraverse(root);
    cout << endl;
    cout << "inorder: ";
    intraverse(root);
    cout << endl;
     cout << "postorder: ";
    posttraverse(root);
    cout << endl;
    return 0;
}

#include <iostream>
#include <stack>
using namespace std;

struct TreeNode
{
    TreeNode* left = NULL;
    TreeNode* right = NULL;
    int value;
};

TreeNode* createAtree()
{
    //随便创建一个
    TreeNode* root = new TreeNode;
    root->value = 1;
    root->left = new TreeNode;
    root->left->value = 2;
    root->right = new TreeNode;
    root->right->value = 3;
    root->left->left = new TreeNode;
    root->left->left->value = 4;
    root->right->left = new TreeNode;
    root->right->left->value = 5;
    root->right->right = new TreeNode;
    root->right->right->value = 6;
    return root;
}

void pretraverse(TreeNode* root)
{
    //逻辑:先把跟结点放到栈里,打印跟结点,且当前结点指向跟结点
    //然后先压右,再压左,下一个循环,还是打印栈顶,当前结点指向栈顶。
    if(root != NULL)
    {
        stack<TreeNode*> hh;
        hh.push(root);
        while(!hh.empty())
        {
            TreeNode* cur = hh.top();
            hh.pop();
            cout << cur->value << " ";
            if(cur->right != NULL)
            {
                hh.push(cur->right);
            }
            if(cur->left != NULL)
            {
                hh.push(cur->left);
            }
        }
    }
}

void intraverse(TreeNode* root)
{
    //逻辑:当前结点如果不为空,则压栈,将当前结点指向左孩子
    //如果当前结点为空,则打印栈顶,并将当前结点指向栈顶,然后在指向当前结点的右孩子
    if(root != NULL)
    {
        stack<TreeNode*> hh;
        while(!hh.empty() || root != NULL)
        {
            if(root != NULL)
            {
                hh.push(root);
                root = root->left;
            }
            else
            {
                root = hh.top();
                hh.pop();
                cout << root->value << " ";
                root = root->right;
            }
            
        }
    }
}

void posttraverse(TreeNode* root)
{
    //思路:前序遍历的方向是中左右,那么同样可以实现中右左,利用另一个栈将中右左的结果保存,最后弹出就变成了左右中
    if(root != NULL)
    {
        stack<TreeNode*> s1;
        stack<TreeNode*> s2;
        s1.push(root);
        while(!s1.empty())
        {
            TreeNode* cur = s1.top();
            s1.pop();
            s2.push(cur);
            if(cur->left != NULL)
            {
                s1.push(cur->left);
            }
            if(cur->right != NULL)
            {
                s1.push(cur->right);
            }
        }

        while(!s2.empty())
        {
            cout << s2.top()->value << " ";
            s2.pop();
        }
    }
}

int main()
{
    TreeNode* root = createAtree();
    cout << "preorder: ";
    pretraverse(root);
    cout << endl;
    cout << "inorder: ";
    intraverse(root);
    cout << endl;
     cout << "postorder: ";
    posttraverse(root);
    cout << endl;
    return 0;
}

层序遍历:

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    vector<int> PrintFromTopToBottom(TreeNode* root) {
        queue<TreeNode*> hh;
        hh.push(root);
        vector<int> res;
        if(root == NULL)
            return res;
        while(!hh.empty())
        {
            TreeNode* front = hh.front();
            if(front->left != NULL)
                hh.push(front->left);
            if(front->right != NULL)
                hh.push(front->right);
            res.push_back(front->val);
            hh.pop();
        }
        return res;
    }
};
5.图的深度优先搜索

在这里插入图片描述

在这里插入图片描述

6.图的广度优先搜索

在这里插入图片描述
在这里插入图片描述

7.最短路径

dijkstra

8.c实现多态
#include<stdio.h>

typedef void(*fun)();   //这样可以直接用fun调用void(*)()的函数

struct base {
    fun _f;
};

struct derived {
    base _b;//实现继承
};

void f1() {
    printf("%s\n", "base");
}
void f2() {
    printf("%s\n", "derived");
}
int main()
{
    base b;     //父类对象
    derived d;  //子类对象
    b._f = f1;
    d._b._f = f2;   //体现继承
    base *p1 = &b;  //父类指针指向父类对象
    p1->_f();
    base *p2 = (base*)&d;   //将父类指针指向子类对象,使用强制转换
    p2->_f();               //指向的地址不变,所以调用子类函数<父类指针指向子类对象,实现多态>
}
9.shared_ptr实现
#include <iostream>

using namespace std;

template <typename T>
class smart_ptr
{
public:
    smart_ptr(T* ptr)
    {
        this->ptr = ptr;
        this->use_count = new int(1);
        *(this->use_count) = 1;
    }
    smart_ptr(const smart_ptr& rhs)
    {
        this->ptr = rhs.ptr;
        this->use_count = rhs.use_count;
        ++(*this->use_count);
    }
    ~smart_ptr()
    {
        cout << "智能指针析构函数:use_count  " << *use_count << endl;
        if(--(*this->use_count) == 0)
        {
            delete this->ptr;
            this->ptr = nullptr;
            delete this->use_count;
            this->use_count = nullptr;
        }
    }
    smart_ptr<T>&operator = (const smart_ptr& rhs)
    {
        if(this != &rhs)
        {
            delete this->ptr;
            delete this->use_count;
            this->ptr = rhs.ptr;
            this->use_count = rhs.use_count;
            (*this->use_count)++;
        }
        return *this;
    }
    T& operator*()
    {
        return *this->ptr;
    }
    T* operator->()
    {
        return this->ptr;
    }
    int get_count()
    {
        return *(this->use_count);
    }
private:
    T* ptr;
    int* use_count;
};

class Test
{
public:
    Test()
    {
        cout << "Test" << endl;
    }
    ~Test()
    {
        cout << "~Test()" << endl;
    }
    int a = 0;
};

smart_ptr<Test> test() 
{
    smart_ptr<Test> p1(new Test);
    p1->a = 10;
    (*p1).a = 30;               // 用到左值的概念了, *operator如果返回T则是左值不能赋值, 改变, 寻址, T&就不一样了
    cout << p1.get_count() << endl;
    smart_ptr<Test> p2(p1);
    smart_ptr<Test> p3 = p1;

    cout << p1.get_count() << endl;
    cout << p2.get_count() << endl;
    cout << p3.get_count() << endl;

    smart_ptr<Test> p4(new Test);
    p4 = p2;
    cout << p4.get_count() << endl;

    return p4;
}

int main()
{
    smart_ptr<Test> p = test();
    cout << p.get_count() << endl;
    cout << p->a << endl;
    cout << (*p).a << endl;
    return 0;
}
10.vector实现
#include <iostream>


template <class T>
class vector
{
    typedef T* iterator;
    typedef const T* const_iterator;
public:
    //构造函数
    vector() : size(0), capacity(0), arr(NULL){}
    vector(int initsize = 0) : size(initsize), capacity(size * 2), arr(NULL)
    {
        arr = new T[capacity];
    }
    vector(int initsize,T xx) : size(initsize), capacity(initsize * 2), arr(NULL)
    {
        arr = new T[capacity];
    }
    vector(iterator start, iterator end)
    {
        size = (end - start) / sizeof(iterator);
        capacity = size * 2;
        arr = new T[capacity];
        int i = 0;
        for(auto iter = start; iter != end; iter++)
        {
            xx[i] = *iter;
            i++;
        }
    }
    //拷贝构造函数
    vector(const vector& rhs) : size(0), capacity(0), arr(NULL)
    {
        *this = rhs;
    }
    bool push_back(const T& value)
    {
        if(size == 0)
        {
            arr = new T[1];
            arr[0] = value;
            size++;
            return true;
        }
        if(size < capacity)
        {
            arr[size] = value;
            size++;
            return true;
        }
        if(size == capacity)
        {

        }
        capacity *= 2;
        T* newarr = new T[capacity];
        for(int i = 0; i < size; i++)
        {
            newarr[i] = arr[i];
        }
        delete[] arr;
        arr = newarr;
        arr[size] = value;
        size++;
        return true;
    }
    bool reserve(int N)
    {
        ;
    }
    void pop_back()
    {
        --size;
    }
    T& front()
    {
        if(size == 0)
            return NULL;
        else
            return arr[0];
    }
    T& back()
    {
        if(size == 0)
            return NULL;
        else
            return arr[size - 1];
    }

    iterator begin()
    {
        return &arr[0];
    }
    iterator end()
    {
        return &arr[size];
    }

    int Size()
    {
        return size;
    }

    int Capacity()
    {
        return capacity;
    }

    //析构函数
    ~vector()
    {
        delete[] arr;
    }

private:
    int size;
    int capacity;
    T* arr;
};
11.线程安全的单例
#include <iostream>
using namespace std;
 
class Singleton
{
public:
	static Singleton *GetInstance()
	{
		return m_Instance;
	}
 
	int GetTest()
	{
		return m_Test;
	}
 
private:
	Singleton() { m_Test = 10; }
	static Singleton *m_Instance;
	int m_Test;
 
	//用内部类销毁单例
	class GC
	{
	public:
		~GC()
		{
			// We can destory all the resouce here, eg:db connector, file handle and so on
			if (m_Instance != NULL)
			{
				cout << "Here is the test" << endl;
				delete m_Instance;
				m_Instance = NULL;
			}
		}
	};
 
	static GC gc;
};
 
Singleton *Singleton::m_Instance = new Singleton();
Singleton::GC Singleton::gc;  //全局对象,程序结束时会掉用它的析构函数
 
int main(int argc, char *argv[])
{
	Singleton *singletonObj = Singleton::GetInstance();
	cout << singletonObj->GetTest() << endl;
 
	system("pause");
	return 0;
}

如果是另一种模式的话,要通过lock来保证线程安全

linux系统可以通过pthread_once保证线程安全

muduo的Singleton

// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)

#ifndef MUDUO_BASE_SINGLETON_H
#define MUDUO_BASE_SINGLETON_H

#include "muduo/base/noncopyable.h"

#include <assert.h>
#include <pthread.h>
#include <stdlib.h> // atexit
/*
线程安全的单例模式类模板
*/

namespace muduo
{

    namespace detail
    {
        // This doesn't detect inherited member functions!
        // http://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions
        template<typename T>
        struct has_no_destroy
        {
            template <typename C> static char test(decltype(&C::no_destroy));
            template <typename C> static int32_t test(...);
            const static bool value = sizeof(test<T>(0)) == 1;
        };
    }  // namespace detail

    template<typename T>
    class Singleton : noncopyable
    {
    public:
        Singleton() = delete;
        ~Singleton() = delete;

        static T& instance()  //创建单例对象并返回
        {
            pthread_once(&ponce_, &Singleton::init);  //保证init函数仅被调用一次,且调用是线程安全的
            assert(value_ != NULL);
            return *value_;
        }

    private:
        static void init()
        {
            value_ = new T();
            if (!detail::has_no_destroy<T>::value)
            {
                ::atexit(destroy);  //在程序结束是调用destroy
            }
        }

        static void destroy()
        {
            typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];
            //T_must_be_complete_type必须是完整类型,完整类型才可以被delete
            T_must_be_complete_type dummy; (void)dummy;

            delete value_;
            value_ = NULL;
        }

    private:
        static pthread_once_t ponce_;
        static T*             value_;
    };

    template<typename T>
    pthread_once_t Singleton<T>::ponce_ = PTHREAD_ONCE_INIT;

    template<typename T>
    T* Singleton<T>::value_ = NULL;

}  // namespace muduo

#endif  // MUDUO_BASE_SINGLETON_H
12.线程池
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)

#ifndef MUDUO_BASE_THREADPOOL_H
#define MUDUO_BASE_THREADPOOL_H

#include "muduo/base/Condition.h"
#include "muduo/base/Mutex.h"
#include "muduo/base/Thread.h"
#include "muduo/base/Types.h"

#include <deque>
#include <vector>

namespace muduo
{

    class ThreadPool : noncopyable
    {
    public:
        typedef std::function<void()> Task;  //任务

        explicit ThreadPool(const string& nameArg = string("ThreadPool"));
        ~ThreadPool();

        // Must be called before start().
        void setMaxQueueSize(int maxSize) { maxQueueSize_ = maxSize; }
        void setThreadInitCallback(const Task& cb)
        {
            threadInitCallback_ = cb;
        }

        void start(int numThreads);
        void stop();

        const string& name() const
        {
            return name_;
        }

        size_t queueSize() const;

        // Could block if maxQueueSize > 0
        // There is no move-only version of std::function in C++ as of C++14.
        // So we don't need to overload a const& and an && versions
        // as we do in (Bounded)BlockingQueue.
        // https://stackoverflow.com/a/25408989
        void run(Task f);

    private:
        bool isFull() const REQUIRES(mutex_);   //任务队列是否满
        void runInThread();
        Task take();        //线程拿任务

        mutable MutexLock mutex_;
        Condition notEmpty_ GUARDED_BY(mutex_);  //非空条件变量
        Condition notFull_ GUARDED_BY(mutex_);   //非满条件变量
        string name_;
        Task threadInitCallback_;           //线程初始回调
        std::vector<std::unique_ptr<muduo::Thread>> threads_;       //线程数组
        std::deque<Task> queue_ GUARDED_BY(mutex_);     //任务队列
        size_t maxQueueSize_;
        bool running_;  //线程池是否处于运行状态
    };

}  // namespace muduo

#endif  // MUDUO_BASE_THREADPOOL_H

// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)

#include "muduo/base/ThreadPool.h"

#include "muduo/base/Exception.h"

#include <assert.h>
#include <stdio.h>

using namespace muduo;

ThreadPool::ThreadPool(const string& nameArg)  //初始化
    : mutex_(),
    notEmpty_(mutex_),
    notFull_(mutex_),
    name_(nameArg),
    maxQueueSize_(0),
    running_(false)
{
}

ThreadPool::~ThreadPool()
{
    if (running_)
    {
        stop();
    }
}

void ThreadPool::start(int numThreads)  //线程池对象开始创建线程
{
    assert(threads_.empty()); //断言此时线程池应该为空
    running_ = true;    //表明正在创建
    threads_.reserve(numThreads);   //预留空间
    for (int i = 0; i < numThreads; ++i)
    {
        char id[32];
        snprintf(id, sizeof id, "%d", i + 1);
        threads_.emplace_back(new muduo::Thread(
            std::bind(&ThreadPool::runInThread, this), name_ + id));
        //线程函数runInThread,线程名:name_ + id
        threads_[i]->start();  //将每个线程启动
    }
    if (numThreads == 0 && threadInitCallback_) //如果线程池大小传入0,且设置了线程初始回调,那么执行初始回调
    {
        threadInitCallback_();
    }
}

void ThreadPool::stop()
{
    {
        MutexLockGuard lock(mutex_);
        running_ = false;  //running变为false后,runinthread解除阻塞,运行结束
        notEmpty_.notifyAll();
    }
    for (auto& thr : threads_)
    {
        thr->join();
    }
}

size_t ThreadPool::queueSize() const
{
    MutexLockGuard lock(mutex_);
    return queue_.size();
}

void ThreadPool::run(Task task)  //让线程池运行这个task,
{
    if (threads_.empty())   //如果线程池为空,则直接运行
    {
        task();
    }
    else
    {
        MutexLockGuard lock(mutex_);    //否则将任务添加到任务队列中,并使用非空条件变量,通知消费者take()
        while (isFull())
        {
            notFull_.wait();
        }
        assert(!isFull());

        queue_.push_back(std::move(task));
        notEmpty_.notify();
    }
}

ThreadPool::Task ThreadPool::take()  //拿任务
{
    MutexLockGuard lock(mutex_);
    // always use a while-loop, due to spurious wakeup
    while (queue_.empty() && running_)  //任务队列不为空
    {
        notEmpty_.wait();
    }
    Task task;
    if (!queue_.empty())
    {
        task = queue_.front();
        queue_.pop_front();
        if (maxQueueSize_ > 0)
        {
            notFull_.notify();
        }
    }
    return task;
}

bool ThreadPool::isFull() const
{
    mutex_.assertLocked();
    return maxQueueSize_ > 0 && queue_.size() >= maxQueueSize_;
}

void ThreadPool::runInThread()  //传入Thread对象的线程函数
{
    try
    {
        if (threadInitCallback_)
        {
            threadInitCallback_();
        }
        while (running_) //当running为真时不停获取任务并执行任务
        {
            Task task(take()); //拿任务
            if (task)
            {
                task();
            }
        }
    }
    catch (const Exception& ex)
    {
        fprintf(stderr, "exception caught in ThreadPool %s\n", name_.c_str());
        fprintf(stderr, "reason: %s\n", ex.what());
        fprintf(stderr, "stack trace: %s\n", ex.stackTrace());
        abort();
    }
    catch (const std::exception& ex)
    {
        fprintf(stderr, "exception caught in ThreadPool %s\n", name_.c_str());
        fprintf(stderr, "reason: %s\n", ex.what());
        abort();
    }
    catch (...)
    {
        fprintf(stderr, "unknown exception caught in ThreadPool %s\n", name_.c_str());
        throw; // rethrow
    }
}
13.阻塞队列
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)
/*
无界队列缓冲区
*/

#ifndef MUDUO_BASE_BLOCKINGQUEUE_H
#define MUDUO_BASE_BLOCKINGQUEUE_H

#include "muduo/base/Condition.h"
#include "muduo/base/Mutex.h"

#include <deque>
#include <assert.h>

namespace muduo
{

    template<typename T>
    class BlockingQueue : noncopyable
    {
    public:
        BlockingQueue()
            : mutex_(),
            notEmpty_(mutex_),
            queue_()
        {
        }

        void put(const T& x)  //生产
        {
            MutexLockGuard lock(mutex_);  //加锁
            queue_.push_back(x);
            notEmpty_.notify(); // wait morphing saves us   //不为空就通知消费者
            // http://www.domaigne.com/blog/computing/condvars-signal-with-mutex-locked-or-not/
        }

        void put(T&& x)
        {
            MutexLockGuard lock(mutex_);
            queue_.push_back(std::move(x));
            notEmpty_.notify();
        }

        T take()  //消费
        {
            MutexLockGuard lock(mutex_);
            // always use a while-loop, due to spurious wakeup
            while (queue_.empty())  //等到队列不为空为止,才能进行消费
            {
                notEmpty_.wait();
            }
            assert(!queue_.empty());
            T front(std::move(queue_.front()));
            queue_.pop_front();
            return std::move(front);
        }

        size_t size() const
        {
            MutexLockGuard lock(mutex_);
            return queue_.size();
        }

    private:
        mutable MutexLock mutex_;
        Condition         notEmpty_ GUARDED_BY(mutex_);  //条件变量  队列不为空
        std::deque<T>     queue_ GUARDED_BY(mutex_);
    };

}  // namespace muduo

#endif  // MUDUO_BASE_BLOCKINGQUEUE_H
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)
/*
有界队列缓冲区
*/

#ifndef MUDUO_BASE_BOUNDEDBLOCKINGQUEUE_H
#define MUDUO_BASE_BOUNDEDBLOCKINGQUEUE_H

#include "muduo/base/Condition.h"
#include "muduo/base/Mutex.h"

#include <boost/circular_buffer.hpp>
#include <assert.h>

namespace muduo
{

    template<typename T>
    class BoundedBlockingQueue : noncopyable
    {
    public:
        explicit BoundedBlockingQueue(int maxSize)
            : mutex_(),
            notEmpty_(mutex_),
            notFull_(mutex_),
            queue_(maxSize)
        {
        }

        void put(const T& x)
        {
            MutexLockGuard lock(mutex_);
            while (queue_.full())
            {
                notFull_.wait();
            }
            assert(!queue_.full());
            queue_.push_back(x);
            notEmpty_.notify();  //非空就通知消费者来拿
        }

        void put(T&& x)
        {
            MutexLockGuard lock(mutex_);
            while (queue_.full())
            {
                notFull_.wait();
            }
            assert(!queue_.full());
            queue_.push_back(std::move(x));
            notEmpty_.notify();
        }

        T take()
        {
            MutexLockGuard lock(mutex_);
            while (queue_.empty())
            {
                notEmpty_.wait();
            }
            assert(!queue_.empty());
            T front(std::move(queue_.front()));
            queue_.pop_front();
            notFull_.notify();      //没满就通知生产者生产
            return std::move(front);
        }

        bool empty() const
        {
            MutexLockGuard lock(mutex_);
            return queue_.empty();
        }

        bool full() const
        {
            MutexLockGuard lock(mutex_);
            return queue_.full();
        }

        size_t size() const
        {
            MutexLockGuard lock(mutex_);
            return queue_.size();
        }

        size_t capacity() const
        {
            MutexLockGuard lock(mutex_);
            return queue_.capacity();
        }

    private:
        mutable MutexLock          mutex_;
        Condition                  notEmpty_ GUARDED_BY(mutex_);   //非空的条件变量
        Condition                  notFull_ GUARDED_BY(mutex_);   //非满的条件变量
        boost::circular_buffer<T>  queue_ GUARDED_BY(mutex_);
    };

}  // namespace muduo

#endif  // MUDUO_BASE_BOUNDEDBLOCKINGQUEUE_H
    }

    void put(T&& x)
    {
        MutexLockGuard lock(mutex_);
        while (queue_.full())
        {
            notFull_.wait();
        }
        assert(!queue_.full());
        queue_.push_back(std::move(x));
        notEmpty_.notify();
    }

    T take()
    {
        MutexLockGuard lock(mutex_);
        while (queue_.empty())
        {
            notEmpty_.wait();
        }
        assert(!queue_.empty());
        T front(std::move(queue_.front()));
        queue_.pop_front();
        notFull_.notify();      //没满就通知生产者生产
        return std::move(front);
    }

    bool empty() const
    {
        MutexLockGuard lock(mutex_);
        return queue_.empty();
    }

    bool full() const
    {
        MutexLockGuard lock(mutex_);
        return queue_.full();
    }

    size_t size() const
    {
        MutexLockGuard lock(mutex_);
        return queue_.size();
    }

    size_t capacity() const
    {
        MutexLockGuard lock(mutex_);
        return queue_.capacity();
    }

private:
    mutable MutexLock          mutex_;
    Condition                  notEmpty_ GUARDED_BY(mutex_);   //非空的条件变量
    Condition                  notFull_ GUARDED_BY(mutex_);   //非满的条件变量
    boost::circular_buffer<T>  queue_ GUARDED_BY(mutex_);
};

} // namespace muduo

#endif // MUDUO_BASE_BOUNDEDBLOCKINGQUEUE_H

##### 14.C++实现hashtable

```cpp
#ifndef _HASH_TABLE_H
#define _HASH_TABLE_H

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

/************************************************************************
   created: 2018/01/20
   class: HashTable
   author: linyi
   usage: 哈希表操作
************************************************************************/

using uint = unsigned int;

/** hash table element*/
struct htItem{
    htItem  *next;
    std::string key_string;
    uint fid;
	htItem() :next(nullptr), fid(0),key_string("default str") {};
};

class HashTable
{
public:
	HashTable(int tSize);
	~HashTable();
	uint htCapacity();	
	bool htSet(std::string key, uint fid);	// 插入一个hash值
	htItem* htGet(std::string key);	// 查找
	bool htDel(std::string key);	// 删除
	void printHashTable();		    // 打印
private:
	uint tableSize;	
	std::vector<htItem*> ht;
	uint bkdrHash(std::string key);	// 计算字符串hash值
	uint htIndex(std::string key);	// 计算属于哪一个槽
};

#endif
#include "hashTable.h"

HashTable::HashTable(int tSize)
{
	tableSize = tSize;
	ht.resize(tSize);
	std::for_each(ht.begin(), ht.end(), [](htItem* &r){r = new htItem(); });
}

HashTable::~HashTable()
{

	for (int i = 0; i < tableSize; ++i)
	{
		htItem * tmp = ht[i];
		htItem * next = tmp->next;
		while (tmp)
		{
			delete tmp;
			tmp = next;
			if (tmp == nullptr)
				break;
			next = next->next;
		}		
	}
}

uint HashTable::htCapacity()
{
	return tableSize;
}

uint HashTable::bkdrHash(std::string key)
{
	uint seed = 131;
	uint hash = 0;
	uint idx = 0;
	char k = key[idx];
	while (k != '\n' && k != 0)
	{
		hash = hash * seed + k;
		k = key[++idx];
	}
	return (hash & 0x7FFFFFFF);
}

uint HashTable::htIndex(std::string key){
	uint hashedKey = bkdrHash(key);	
	return (uint)hashedKey % this->tableSize;
}

bool HashTable::htSet(std::string key, uint fid){
	uint i = htIndex(key);	
	htItem *item = ht[i];	
	while (item->next)
	{
		//已经存在的话则直接更新值
		if (key == item->next->key_string){
			item->next->fid = fid;
			return true;
		}
		else{
			item = item->next;
		}
	}
	item->next = new htItem();
	item->next->fid = fid;
	item->next->key_string = key;
	item->next->next = nullptr;
	return true;
}

htItem* HashTable::htGet(std::string key){
    uint i = htIndex(key);
	
    htItem *item = ht[i]->next;
    while (item)
    {
        if (key == item->key_string){
            return item;            
        }
        item = item->next;
    }
    return nullptr;
}

bool HashTable::htDel(std::string key){
    uint i = htIndex(key);
	
    htItem *item = ht[i];
    while (item->next){
		// 找到,删除节点
        if (key == item->next->key_string){
            htItem *tmp = item->next;
            item->next = tmp->next;
			delete tmp;
            return true;
        }
        item = item->next;
    }
    return false;
}

void HashTable::printHashTable()
{
    htItem *item;
	for (uint i = 0; i < tableSize; i++)
    {
        item = ht[i]->next;
		std::cout << i << ":\n";
        while (item)
        {            
			std::cout << item->key_string << " => " << item->fid << std::endl;
            item = item->next;
        }		
    }
}

/*
HashTable ht(4);
ht.htSet("abc", 1);
ht.htSet("asbc", 2);
ht.htSet("abdc", 3);
ht.htSet("abfc", 4);
ht.htSet("asbc", 5);
ht.printHashTable();
*/
15.c语言实现hashtable
#ifndef _HASH_TABLE_H
#define _HASH_TABLE_H
#include <stdlib.h>
#include <memory.h>
#include <stdio.h>
#include <string.h>
#define HASH_TABLE_CAPACITY 20

typedef unsigned int uint;

/** hash table element*/
typedef struct _htItem{
    struct _htItem  *next;
    char *key_string;
    uint fid;

} htItem;

/** init the hashTable 构造函数,申请哈希表的空间*/
void htInit(htItem **ht, uint length);

/** set hashTable element 哈希表中插入一个值*/
uint htSet(char *key, uint val, htItem **ht);

/** get element from hashtable 从哈希表中获得一个对应的key*/
htItem* htGet(char *key, htItem **ht);

/** Delete element from hashTable 从哈希表中删除一个key*/
int htDel(char *key, htItem **ht);

/** BKDR hash function 对string进行散列得到一个整数值*/
uint bkdrHash(char *key);

/** get the index of hash table 根据key计算一个整数值,然后获得对应的槽位*/
uint htIndex(char *key, htItem **ht);

/** get hashTable elements */
uint htLen(htItem **ht);

/*打印哈希表*/
void print_hashTable(htItem **ht);
#endif
#include "hashTable.h"

/*初始化HashTable*/
void htInit(htItem **ht, uint length){
    int i;
    for (i = 0; i<length; i++){
        ht[i] = (htItem*)malloc(sizeof(htItem));
        memset(ht[i], 0, sizeof(htItem));
    }
    ht[0]->fid = length;
}

/** get hashTable elements 进行对应的hash值的搜索,如果找到则返回该节点*/
htItem* htGet(char *key, htItem **ht){
    uint i = htIndex(key, ht);
    htItem *item = ht[i]->next;
    htItem *tmp = (htItem*)malloc(sizeof(htItem));
    memset(tmp, 0, sizeof(htItem));
    while (item)
    {
        if (strcmp(key, item->key_string) == 0){
            return item;
            tmp->fid = item->fid;
            tmp->key_string = item->key_string;
            return tmp;
        }
        item = item->next;
    }
    return NULL;
}

/** set hashTable element 插入新的hash值*/
uint htSet(char *key, uint fid, htItem **ht){
    uint i = htIndex(key, ht);
    htItem *item = ht[i];
    while (item->next)
    {
    //已经存在的话则直接更新值
        if (strcmp(key, item->next->key_string) == 0){
            item->next->fid = fid;
            return 0;
        }
        else{
            item = item->next;
        }
    }
    item->next = (htItem*)malloc(sizeof(htItem));
    item->next->fid = fid;
    item->next->key_string = key;
    item->next->next = NULL;
    return 0;
}

/** delete one element of hashtable  删除hash值*/
int htDel(char *key, htItem **ht){
    uint i = htIndex(key, ht);
    htItem *item = ht[i];
    while (item->next){
        if (strcmp(key, item->next->key_string) == 0){
            htItem *tmp = item->next;
            item->next = tmp->next;
            free(tmp);
            return 0;
        }
        item = item->next;
    }
    return -1;
}

/** BKDR hash function  对字符串进行散列,得到一个整数的hash值*/
uint bkdrHash(char *key)
{
    uint seed = 131;
    uint hash = 0;
    while (*key != '\n' && *key != 0)
    {
        hash = hash * seed + (*key++);
    }
    return (hash & 0x7FFFFFFF);
}

/** get the index of hash table  根据得到的hash值选择一个槽位置*/
uint htIndex(char *key, htItem **ht){
    uint hashedKey = bkdrHash(key);
    uint length = (ht[0]->fid - 1);
    return (uint)hashedKey % length + 1;
}

/** get element number in the hashtable */
uint htLen(htItem **ht){
    uint alength = ht[0]->fid;
    uint i, length = 0;
    for (i = 1; i < alength; i++){
        if (ht[i]->next) {
            length++;
        }
    }
    return length;
}

/** get capacity of hashtable */
uint htCapacity(htItem **ht)
{
    return ht[0]->fid;
}

void print_hashTable(htItem **ht)
{
    uint length = ht[0]->fid;
    uint i;
    htItem *item;
    for (i = 1; i < length; i++)
    {
        item = ht[i]->next;
        while (item)
        {
            printf("%s => %d\n", item->key_string, item->fid);
            item = item->next;
        }
    }
}
发布了27 篇原创文章 · 获赞 70 · 访问量 9401

猜你喜欢

转载自blog.csdn.net/qq_23905237/article/details/99501241
今日推荐