複試上機指南之數據結構二

二叉樹

二叉樹的前、中、後序、層次遍歷

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(),用來查找特定元素,返回值是該元素的迭代器。

  1. 輸入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;
}
  1. 在輸入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;
  1. 給一個以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]++;
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章