二叉樹
二叉樹的前、中、後序、層次遍歷
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]++;
}
}