冒泡
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;
}
}
}