二叉树
二叉树的前、中、后序、层次遍历
struct tree{
char c;
tree* leftnode;
tree* rightnode;
};
//先序遍历
void preorder(tree* root){
if(root==NULL){
return;
}
cout<<root->c;
preorder(root->leftnode);
preorder(root->rightnode);
return;
}
//中序遍历
void inorder(tree* root){
if(root==NULL){
return;
}
preorder(root->leftnode);
cout<<root->c;
preorder(root->rightnode);
return;
}
//后序遍历
void postorder(tree* root){
if(root==NULL){
return;
}
preorder(root->leftnode);
preorder(root->rightnode);
cout<<root->c;
return;
}
//层序遍历
void levelorder(tree* root){
queue<tree*>myQueue;
if(root!=NULL){
myQueue.push(root);
}
while(!myQueue.empty()){
tree* current = myQueue.front();
myQueue.pop();
cout<<current.c;
if(current->leftchild != NULL){
myQueue.push(current->leftnode);
}
if(current->rightchild != NULL){
myQueue.push(current->rightnode);
}
}
}
二叉树的创建
按照前序、中序、后序给出的字符串按照给出的顺序创建(以下代码)即可,若没有给出顺序,只是一个字符串,按照层次遍历的顺序创建字符串。
//给一个字符串,创建一个二叉树
tree *build(int& position,string str){
char a = str[position++];
if(a=='#'){
return NULL;
}
tree* node = new tree;
node->c = a;
node->leftnode = NULL;
node->rightnode = NULL;
node->leftnode = build(position,str);
node->rightnode = build(position,str);
return node;
}
根据前序、中序或者后序中序确定一个二叉树
struct tree{
char c;
tree* leftnode;
tree* rightnode;
tree(char a): c(a),leftnode(NULL),rightnode(NULL){}
};
//若是给的后序的话,则char a= s1[s1.size()-1],后面一样;
tree* build(string s1,string s2){
if(s1.size()==0){
return NULL;
}
char a=s1[0];
tree* node=new tree(a);//构造函数
int position = s2.find(a);
node->leftnode = build(s1.substr(1,position),s2.substr(0,position));
node->rightnode = build(s1.substr(position+1),s2.substr(position+1));
return node;
}
二叉排序树
构建一个二叉排序树
struct tree{
int a;
tree* leftnode;
tree* rightnode;
tree(int c): a(c),leftnode(NULL),rightnode(NULL){}
};
//构建二叉排序树
tree* insert(tree* root,int x,int father){
if(root == NULL){
root = new tree(x);
cout<<father<<endl;
}else if(x<root->a){
root->leftnode = insert(root->leftnode,x,root->a);//左右子树都是一个二叉排序树,直接调用就行。
}else if(x>root->a){
root->rightnode = insert(root->rightnode,x,root->a);
}
return root;
}
优先队列
优先队列,又称为优先级队列、堆。优先队列是一种特殊的队列,除了具有队列的先入先出,队列头出,队列尾入的结构特点,优先队列最重要的就是要实现快速得到队列中优先级最高的元素,因此,优先队列有一定的顺序特点,这是一种弱序,即队列头部的那个元素是优先级最高的,我们往往以元素值的大小作为优先级来讨论,比如说,数值大的优先级高,则优先队列元素会按一定规则的大小顺序排列,从而使得在队列头部的元素始终保持数值最大(优先级最高)的特点。总之,优先队列的目的就是实现将元素入队列,并快速返回队列优先级最高优先级元素。
可以理解为大顶堆、小顶堆,在初始化的时候可以指定按照大或小顶堆排序,不指定的话默认是大顶堆,也就是优先级高(数值大)的在最前面。
下面是默认初始化和指定初始化的三种方式:
#include<queue>//头文件和普通队列一样
//大顶堆也就是默认的方式,输入1 2 3 4 5 6,输出6
int n,a;
priority_queue<int,vector<int>,less<int> > p;
cin>>n;
for(int i=0;i<n;i++){
cin>>a;
p.push(a);
}
cout<<p.top()<<endl;
//小顶堆的方式,输入1 2 3 4 5 6,输出1
int n,a;
priority_queue<int,vector<int>,greater<int> > p;
cin>>n;
for(int i=0;i<n;i++){
cin>>a;
p.push(a);
}
cout<<p.top()<<endl;
//默认方式,输入1 2 3 4 5 6,输出6
int n,a;
priority_queue<int> p;
cin>>n;
for(int i=0;i<n;i++){
cin>>a;
p.push(a);
}
cout<<p.top()<<endl;
散列表
在STL中有一个unordered_map即无序映射,其第层是散列表实现的。map是有序映射其底层是红黑树实现的,顾有一定的顺序;在使用的时候两者操作是相同的,可以使用map,但是在遇到要求性能特别高的时候,我们可以将map改为unordered_map。
map小技巧
关于map之前介绍STL的时候写过,这里记录一些使用时的技巧。
在map中常用的有find(),用来查找特定元素,返回值是该元素的迭代器。
- 输入N个学生的信息,进行查询,我们最直观想到的时使用结构体,其实这个题没有对信息进一步的操作,所以我们可以使用字符串来解决,将学号看作key,将字符串的信息作为values,查询到key时,直接输出str。
map<string,strng> student;
for(int i=0;i<n;i++){
string str;
getline(cin,str);//使用getline是因为它可以接收空格。
int pos = str.find(' ');//第一个输入的是学号作为key,values是str,即寻找分界点。
string key = str.substr(0.pos);//学号作为关键字
student[key] = str;//信息作为映射值。
}
//输出
for(int i=0;i<m;i++){
string key;
cin>>key;
string answer = student[key];
if(answer == ' '){
answer = "No answer!";
}
cout<<answer<<endl;
}
- 在输入key、values时我们往往通过key寻找values,但是如果题目中要求既可以通过key寻找values,又可以通过values输出key,我们当然可以通过建立两个map来实现,但是操作有些繁琐,其实我们可以直接建立双向映射同时放在通一个映射中,具体看代码。
map<string,string>m;
string s;
int pos = s.find(']');//分界点
string key = s.substr(0,pos+1);//key
string value = s.substr(pos+2);//key空格之后的都是values.
m[key] = value;
m[value] = key;
//查找输出
strig ke;
getline(cin,ke);
string answer = m[ke];
if(answer == ""){
answer = "what?";
}else if(answer[0] == '['){
answer=answer.substr(1,answer.size()-2);//删除字符中两侧的[]。
}
cout<<answer<<endl;
- 给一个以0、1组成的字符串,返回每个子串出现的次数。
string str;
cin>>str;
map<string,int>m;
for(int i=0;i<=str.size();i++){
for(int j=0;j<i;j++){
string key = str.substr(j,i-j);
m[key]++;
}
}