您的位置:首页 > 编程语言 > C语言/C++

二叉搜索树转换成一个排序的双向链表和实现一个线程安全且高效单例类——题集(二十一)

2017-08-06 17:52 681 查看
二叉搜索树转换成一个排序的双向链表和实现一个线程安全且高效单例类——题集(二十一)
       今天分享一下实现二叉搜索树转换成一个排序的双向链表和用C++实现一个线程安全且高效单例类的源代码和运行示例。

      将二叉搜索树转换成一个排序的双向链表的源代码和运行示例。

       提示:要求不能创建任何新的结点,只能调整树中结点指针的指向,也就是left当prev,right当next。--中序线索化的变型。

源代码如下:

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

TreeNode* SortList(TreeNode* root){//二叉搜索树转换成一个排序的双向链表
if(root==NULL) return root;
stack<TreeNode*> tmp;
TreeNode* head=NULL;
TreeNode* cur=root;
TreeNode* prev=NULL;

while(cur || !tmp.empty()){
while(cur){
tmp.push(cur);
cur=cur->left;
}

cur=tmp.top();
tmp.pop();
if(head==NULL){
head=cur;
}
else{
prev->right=cur;
}
cur->left=prev;
prev=cur;
cur=cur->right;
}

return head;
}

void TestTree29(){//搜索二叉树转换成一个排序的双向链表
TreeNode * root0=new TreeNode(8);
TreeNode * root1=new TreeNode(5);
TreeNode * root2=new TreeNode(14);
TreeNode * root3=new TreeNode(2);
TreeNode * root4=new TreeNode(6);
TreeNode * root5=new TreeNode(18);

root0->left = root1;
root0->right = root2;
root1->left = root3;
root1->right = root4;
root2->right = root5;

TreeNode* head=SortList(root0);//二叉搜索树转换成一个排序的双向链表
cout<<"二叉搜索树转换成一个排序的双向链表"<<endl;

TreeNode* prev=NULL;
cout<<"正序打印: ";//->next/right
while(head!=NULL){
cout<<head->val<<" ";
prev=head;
head=head->right;
}
cout<<endl;

cout<<"逆序打印: ";//->prev/left
while(prev!=NULL){
cout<<prev->val<<" ";
head=prev;
prev=prev->left;
}
cout<<endl;
}

int main(){
TestTree29();//搜索二叉树转换成一个排序的双向链表

system("pause");
return 0;
}


运行结果:


 
     
C++实现一个线程安全且高效单例类的源代码和运行示例。

     
单例模式:单例类保证全局只有一个唯一实例对象。且单例类提供获得该唯一实例的接口。

     
懒汉模式

优点:第一次调用才初始化,加载类时比较快,且避免内存浪费。

缺点:但是在运行时获取对象的速度比较慢,线程不安全,可利用双重检查加锁来提高效率,保证线程安全。

       饿汉模式

优点:简洁,不用加锁,效率高,且线程安全。获取对象的速度比较快。 

缺点:类加载时就初始化,所以加载类时比较慢,且浪费内存。

源代码如下:

#include<iostream>
using namespace std;
#include <thread>
#include <mutex>
#include <stdexcept>

//实现一个线程安全的单例模式
//懒汉模式-加互斥锁
class LazyModel{
public:
//得到对象
static LazyModel* GetObject(){
if(_object==NULL){//双重判断加锁机制
std::lock_guard<std::mutex> lck(_mutx);
if(_object==NULL){
LazyModel* tmp=new LazyModel();
_object=tmp;
}
}
return _object;
}
//删除对象
static void DelObject(){
std::lock_guard<std::mutex> lck(_mutx);
if(_object){
delete _object;
_object=NULL;
}
}

//打印对象
void Print(){
cout<<_data<<endl;
}
private:
//构造
LazyModel()
:_data(1)
{}

LazyModel(const LazyModel&);
LazyModel& operator=(const LazyModel&);

//析构
~LazyModel(){}

static LazyModel* _object;
static mutex _mutx;
int _data;
};
LazyModel* LazyModel::_object=NULL;
mutex LazyModel::_mutx;

void TestLazyModel(){//懒汉模式
cout<<"懒汉模式"<<endl;
LazyModel::GetObject()->Print();
LazyModel::DelObject();
cout<<endl;
}

//饿汉模式
class HungerModel{
public:
//得到对象
static HungerModel* GetObject(){
static HungerModel sigle;//静态全局对象
return &sigle;
}

//打印对象
void Print(){
cout<<_data<<endl;
}
private:
//构造
HungerModel()
:_data(2)
{}

HungerModel(const HungerModel&);
HungerModel& operator=(const HungerModel&);

//析构
~HungerModel(){}

int _data;
};

void TestHungerModel(){//饿汉模式
cout<<"饿汉模式"<<endl;
HungerModel::GetObject()->Print();
cout<<endl;
}

int main(){
TestLazyModel();//懒汉模式
TestHungerModel();//饿汉模式

system("pause");
return 0;
}
运行结果:


 
      感觉很难呢,写的有点挫,如果有错误,请一定要指出来。

      分享如上,如有错误,望斧正!愿大家学得开心,共同进步!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐