目录
二叉树的实现
#include<iostream>
using namespace std;
#include<iostream>
using namespace std;
template<typename T>//层序遍历时需要使用的队列
struct QNode
{
T elem;
QNode*next;
};
template<typename T>
class LinkQueue
{
QNode<T> *front,*rear;
public:
LinkQueue():front(NULL),rear(NULL){};
~LinkQueue()
{
QNode<T>*p;
while(!front)
{
p=front;front=front->next;delete p;
}
}
bool IsEmpty()const {return front==NULL;}
int Length()const
{
QNode<T>* p=front;
int i=0;
while(p)
{i++;p=p->next;}
return i;
}
void InQueue(T&e)
{
if(IsEmpty())
{
front=rear=new QNode<T>;
front->elem=e;
front->next=NULL;
}
else
{
QNode<T>*node=new QNode<T>;
node->elem=e;
node->next=NULL;
rear=rear->next=node;
}
}
T OutQueue()
{
if(IsEmpty()) {cout<<"队列为空"<<endl;exit(0); }
T e=front->elem;
QNode<T>*p=front;
front=front->next;
if(front==NULL) rear=NULL;
delete p;
return e;
}
};
template<class T>
class BTree;
template<class T>
class BTNode//二叉树节点类
{
friend class BTree<T>;
// friend class BSTree<T>;
T data;
BTNode<T>*left;
BTNode<T>*right;
public:
BTNode();
BTNode(const T&e){data=e;}
BTNode(const T&e,BTNode<T>*l,BTNode<T>*r){data=e; left=l; right=r;}//给定值和左右指针的构造函数
~BTNode(){};
T value() const {return data;}
BTNode<T>*lch()const{return left;}
BTNode<T>*rch()const{return right;}
void setlch(BTNode<T>*l){left=l;}
void setrch(BTNode<T>*r){right=r;}
void servalue(const T&val){data=val;}
};
template<class T>
class BTree
{
protected:
BTNode<T>*root;
public:
BTree(){root=NULL;}
BTree(BTNode<T>*r){root=r;}
~BTree(){DeleteBTree(root);}
DeleteBTree(BTNode<T>*t)
{
if(t)
{
BTNode<T>*l=t->left;
BTNode<T>*r=t->right;
delete t;
DeleteBTree(l);
DeleteBTree(r);
}
return 0;
}
bool IsEmpty()const{return root==NULL;}
void visit(const T&data){cout<<data<<" ";}//不可直接在外部访问私有成员
BTNode<T>*&Root(){return root;}
BTNode<T>*ls(BTNode<T>*c){return c->left;}
BTNode<T>*rs(BTNode<T>*c){return c->right;}
void create(const T&data,BTree<T>&leftTree,BTree<T>&rightTree);
void create(BTNode<T>*&r)//先序遍历构造二叉树
{
T ch;
cin>>ch;
if(ch=='#') r=NULL;
else{
r=new BTNode<T>(ch);
create(r->left);
create(r->right);
}
}
void PreOrder(BTNode<T>*root)
{
if(root==NULL) return;
visit(root->value());
PreOrder(root->lch);
PreOrder(root->rch);
}
void InOrder(BTNode<T>*root)
{
if(root==NULL) return;
InOrder(root->lch);
visit(root->value());
InOrder(root->rch);
}
void PostOrder(BTNode<T>*root)
{
if(root==NULL) return;
PostOrder(root->lch);
PostOrder(root->rch);
visit(root->value());
}
void LevelOrder(BTNode<T>*root)
{
LinkQueue<BTNode<T>*>t;//队列节点类型为二叉树节点的指针
BTNode<T>*p=root;
if(p) t.InQueue(p);
while(!t.IsEmpty())
{
p=t.OutQueue();
visit(p->value());
if(p->lch())
t.InQueue(p->lch());
if(p->rch())
t.InQueue(p->rch());
}
}
};
哈夫曼树与编码的实现
#include<iostream>
#include<queue>
#include<vector>
#include<map>
using namespace std;
template<class T>
class HTree;
template<class T>
class HTNode//二叉树节点类
{
friend class HTree<T>;
// friend class BSTree<T>;
T data;
HTNode<T>*left;
HTNode<T>*right;
int wgt;
public:
HTNode();
HTNode(const T&e,int w){data=e;left=NULL;right=NULL;w=wgt;}
HTNode(HTNode<T>*l,HTNode<T>*r,int w){ left=l; right=r; wgt=w;}//给定值和左右指针的构造函数
~HTNode(){};
T& value() {return data;}
HTNode<T>*lch()const{return left;}
HTNode<T>*rch()const{return right;}
bool Isleaf(){return !left&&!right;}
};
template<class T>
class HTree
{
protected:
HTNode<T>*root;
public:
HTree(T e,int w) { root=new HTNode<T>(e,w); }
HTree(int w,HTree<T>*l,HTree<T>*r){ root=new HTNode<T>(l->root,r->root,l->weight()+r->weight());}
int weight(){return root->wgt;}
~HTree(){DeleteHTree(root);}
DeleteHTree(HTNode<T>*t)
{
if(t)
{
HTNode<T>*l=t->left;
HTNode<T>*r=t->right;
delete t;
DeleteHTree(l);
DeleteHTree(r);
}
return 0;
}
HTNode<T>*Root(){return root;}
};
template<class T>
class cmp{
public:
bool operator()(HTree<T>*x,HTree<T>*y)
{
return x->weight()<y->weight();
}
};
template<class T>
HTree<T>*BuildHTree(T elem[],int weight[],int n)
{
priority_queue<HTree<T>*,vector<HTree<T>*>,cmp<T> > q;
for(int i=0;i<n;i++)
q.push(new HTree<T>(elem[i],weight[i]));
while(q.size()>1)
{
HTree<T>*l=q.top();
q.pop();
HTree<T>*r=q.top();
q.pop();
HTree<T>*p=new HTree<T>(l->weight()+r->weight(),l,r);
q.push(p);
}
return q.top();
}
typedef vector<bool>HCode;
map<char,HCode>HDic;
template<class T>
void Huffcode(HTNode<T>*r,HCode curr)
{
if(r->Isleaf())
{
HDic[r->value()]=curr;
return;
}
HCode lc=curr;
HCode rc=curr;
lc.push_back(false);
rc.push_back(true);
Huffcode(r->lch(),lc);
Huffcode(r->rch(),rc);
}
int main()
{
cout<<"输入编码数";
int n;
cin>>n;
cout<<"输入要编码的字母";
char* ele=new char[n];
for(int i=0;i<n;i++)
cin>>ele[i];
cout<<"输入对应权值";
int*w=new int[n];
for(int i=0;i<n;i++)
cin>>w[i];
HTree<char>*r=BuildHTree<char>( ele,w,n);
HCode curr;
Huffcode<char>(r->Root(),curr);
cout<<"输入要查询的字母";
char a;
cin>>a;
HCode c=HDic[a];
int nSize = c.size();
for(int i=0;i<nSize;i++)
cout<<c[i]<<" ";
return 0;
}
学到的编程知识
(1)vector<T>
https://www.cnblogs.com/Nonono-nw/p/3462183.html
(2)vector<bool>
vector <bool>是为了当元素都为bool类型时,优化空间所产生的vector<T>的特化版,主要解决的就是节省空间的问题
节省空间的方法是,按照一个二进制位来存储,而不是一个字节。一个字节可以存八个bool值,极大的节省了空间,而且vector <bool>并没有要求底层的存储必须是连续的空间。
vector <bool>提高空间效率的同时降低了时间效率
因为它是按位存的,一个字节存八个bool值,但是要知道第i个bool值的真假,需要进行位运算,效率就会低一些,存的bool值越多花费的时间就越长,这是典型的以时间换空间的策略。
vector <bool>不是一个容器
(3) map<key,value> a
一、 map的特性
所有元素都会根据元素的减值自动被排序。
map的所有元素都是pair,同时拥有实值(value)和键值(key)。
pair的第一个元素会被视为键值,第二个元素会被视为实值。
map不允许两个元素拥有相同的键值。
头文件:#include< map >
二、map的基本构造函数类型
map<string , int >strMap;
map<int ,string >intMap;
map<sring, char>strMap;
map< char ,string>charMap;
map<char ,int>charMap;
map<int ,char >intMap;
三、map的基本操作函数:
begin() //返回指向map头部的迭代器
clear() //删除所有元素
count() //返回指定元素出现的次数
empty() //如果map为空则返回true
end() //返回指向map末尾的迭代器
equal_range() //返回特殊条目的迭代器对
erase() //删除一个元素
find() //查找一个元素。查的是 健
//当所查找的关键key出现时,它返回数据所在对象的位置,如果沒有,返回iter与end()函数的值相同。
get_allocator() //返回map的配置器
insert() //插入元素
key_comp() //返回比较元素key的函数
lower_bound() //返回键值>=给定元素的第一个位置
max_size() //返回可以容纳的最大元素个数
rbegin() //返回一个指向map尾部的逆向迭代器
rend() //返回一个指向map头部的逆向迭代器
size() //返回map中元素的个数
swap() //交换两个map
upper_bound() //返回键值>给定元素的第一个位置
value_comp() //返回比较元素value的函数
四、map添加数据
map<int ,string> maplive;
pair<int,string> value(1,"a");maplive.insert(value);
//等价于maplive.insert(pair<int,string>(1,"a"));
maplive.insert(map<int,string>::value_type(1,"a"));
maplive[1]="a";//map中最简单最常用的插入添加!
版权声明:优快云博主「杨青葱」的原创,遵循CC 4.0 BY-SA版权协议,转载请附上
原文链接:https://blog.youkuaiyun.com/LUSH_BOY/article/details/113483998