目录
持续完善...
快排(划分算法)
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
int n = nums.size();
partition(nums, 0, n-1);
return nums;
}
void partition(vector<int>& nums, int left, int right)
{
if (left >= right) return;
int index = rand()%(right - left +1)+left;
swap(nums[left], nums[index]);
int i = left, j = right;
while (i < j)
{
while (i < j && nums[left] <= nums[j]) --j;
while (i < j && nums[left] >= nums[i]) ++i;
swap(nums[i], nums[j]);
}
swap(nums[i], nums[left]);
partition(nums, left, i-1);
partition(nums, i+1, right);
}
};
堆排
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
void adjust(int arr[], int len, int index)
{
int left = 2*index + 1;
int right = 2*index + 2;
int maxIdx = index;
if(left<len && arr[left] > arr[maxIdx]) maxIdx = left;
if(right<len && arr[right] > arr[maxIdx]) maxIdx = right; // maxIdx是3个数中最大数的下标
if(maxIdx != index) // 如果maxIdx的值有更新
{
swap(arr[maxIdx], arr[index]);
adjust(arr, len, maxIdx); // 递归调整其他不满足堆性质的部分
}
}
void heapSort(int arr[], int size)
{
for(int i=size/2 - 1; i >= 0; i--) // 对每一个非叶结点进行堆调整(从最后一个非叶结点开始)
{
adjust(arr, size, i);
}
for(int i = size - 1; i >= 1; i--)
{
swap(arr[0], arr[i]); // 将当前最大的放置到数组末尾
adjust(arr, i, 0); // 将未完成排序的部分继续进行堆排序
}
}
int main()
{
int array[8] = {8, 1, 14, 3, 21, 5, 7, 10};
heapSort(array, 8);
for(auto it: array)
{
cout<<it<<endl;
}
return 0;
}
shared_ptr
源自:自己实现一个智能指针_jeak_yang的博客-CSDN博客_实现智能指针
#include <iostream>
template<class T>
class SmartPtr
{
public:
SmartPtr(T* p = nullptr)
{
ptr = p;
if (p == nullptr)
ref_count = new int(0);
else
ref_count = new int(1);
}
~SmartPtr()
{
if (ptr)
{
if (--(*ref_count) == 0)
{
delete ptr;
delete ref_count;
}
}
}
SmartPtr(const SmartPtr& s)
{
ptr = s.ptr;
ref_count = s.ref_count;
(*ref_count)++;
}
SmartPtr& operator=(const SmartPtr& s)
{
if (ptr == s.ptr)
return *this;
if (ptr)
{
if (--(*ref_count) == 0)
{
delete ptr;
delete ref_count;
}
}
ptr = s.ptr;
ref_count = s.ref_count;
(*ref_count)++;
return *this;
}
T* operator->()
{
return ptr;
}
SmartPtr& operator*()
{
return *this;
}
int use_count()
{
return *ref_count;
}
private:
T* ptr;
int *ref_count;
};
int main()
{
int *arry = new int[3];
SmartPtr<int> sp(arry);
std::cout << sp.use_count() << std::endl;
SmartPtr<int> sp1;
sp1 = sp;
SmartPtr<int> sp2(sp1);
std::cout << sp.use_count() << std::endl;
std::cout << sp1.use_count() << std::endl;
std::cout << sp2.use_count() << std::endl;
std::cout << "end" << std::endl;
return 0;
}
实现内存拷贝函数
char* strcpy(char* dst, const char* src)
{
assert(dst!=nullptr && src!=nullptr);
char* ret = dst;
while ((*dst++ = *src)!='\0');
return ret;
}
实现 String 类
源自:让我们一步一步实现一个完整的 String 类:构造、拷贝、赋值、移动和析构_(ÒωÓױ)-CSDN博客
class String {
public:
// 构造:默认(传参)、拷贝构造、移动构造
String(const char *str = nullptr);
String(const String &other);
String(String &&other);
// 析构
~String();
// 赋值:拷贝赋值、移动赋值
String &operator=(const String &other);
String &operator=(String &&other);
private:
char *m_data;
};
String::String(const char *str)
{
if (str == nullptr) {
m_data = new char[1];
*m_data = '\0';
cout << "Default constructor" << endl;
}
else {
int length = strlen(str);
m_data = new char[length + 1];
strcpy(m_data, str);
cout << "Pass argument constructor" << endl;
}
}
String::String(const String &other)
{
int length = strlen(other.m_data);
m_data = new char[length + 1];
strcpy(m_data, other.m_data);
cout << "Copy constructor" << endl;
}
String::String(String &&other)
{
m_data = other.m_data;
other.m_data = nullptr;
cout << "Move constructor" << endl;
}
String::~String()
{
delete[] m_data;
cout << "Destructor" << endl;
}
String &String::operator=(const String &other)
{
if (this != &other) {
if (!m_data) delete[] m_data;
int length = strlen(other.m_data);
m_data = new char[length + 1];
strcpy(m_data, other.m_data);
}
cout << "Copy assignment" << endl;
return *this;
}
String &String::operator=(String &&other)
{
if (this != &other) {
delete[] m_data;
m_data = other.m_data;
other.m_data = nullptr;
}
cout << "Move assignment" << endl;
return *this;
}
单例模式
有两种懒汉和饿汉:
饿汉:饿了就饥不择⻝了,所以在单例类定义的时候就进⾏实例化。
懒汉:顾名思义,不到万不得已就不会去实例化类,也就是在第⼀次⽤到的类实例的时候才会
去实例化。
饿汉模式
#include <iostream>
#include <algorithm>
using namespace std;
class SingleInstance {
public:
static SingleInstance* GetInstance() {
static SingleInstance ins;
return &ins;
}
~SingleInstance(){};
private:
//涉及到创建对象的函数都设置为private
SingleInstance() { std::cout<<"SingleInstance() 饿汉"<<std::endl;}
SingleInstance(const SingleInstance& other) {};
SingleInstance& operator=(const SingleInstance& other) {return *this;}
};
int main(){
//因为不能创建对象所以通过静态成员函数的⽅法返回静态成员变量
SingleInstance* ins = SingleInstance::GetInstance();
return 0;
}
//输出 SingleInstance() 饿汉
懒汉模式
由于要确保在运行时只执行一次实例的创建,因此在创建实例前需要加锁
#include <pthread.h>
#include <iostream>
#include <algorithm>
using namespace std;
class SingleInstance {
public:
static SingleInstance* GetInstance() {
if (ins == nullptr) {
pthread_mutex_lock(&mutex);
if (ins == nullptr) {
ins = new SingleInstance();
}
pthread_mutex_unlock(&mutex);
}
return ins;
}
~SingleInstance(){};
//互斥锁
static pthread_mutex_t mutex;
private:
//涉及到创建对象的函数都设置为private
SingleInstance() { std::cout<<"SingleInstance() 懒汉"<<std::endl;}
SingleInstance(const SingleInstance& other) {};
SingleInstance& operator=(const SingleInstance& other) { return *this; }
//静态成员
static SingleInstance* ins;
};
//懒汉式 静态变量需要定义
SingleInstance* SingleInstance::ins = nullptr;
pthread_mutex_t SingleInstance::mutex;
int main(){
//因为不能创建对象所以通过静态成员函数的⽅法返回静态成员变量
SingleInstance* ins = SingleInstance::GetInstance();
delete ins;
return 0;
}
//输出 SingleInstance() 懒汉