数据结构常见算法机试题

一. 二叉树

1. 根据一个字符串建立二叉树

提交网址
读入输入的字符串,建立一颗以指针方式存储的二叉树,以#表示空树。
abc##de#g##f###

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

string s;
struct node{
	char c;
	node *l,*r;
	node(char c):c(c){}
}; 

node* build(int& pos) //pos不能回溯,需为引用类型 
{
	char c = s[pos];
	pos++;  
	if(c != '#'){
		node *p = new node(c);
		p->l = build(pos);
		p->r = build(pos);
		return p;
	}
	else
		return NULL;
}

void inOrder(node *p)
{
	if(p == NULL)
		return;
	inOrder(p->l);
	cout << p->c;
	inOrder(p->r);
}

int main()
{
	int pos = 0;
	while(cin >> s){
		node *root = build(pos);
		inOrder(root);
		cout << endl;
	}
	return 0;	
}

2. 根据两个字符串建立二叉树

也就是给定前序中序,来确定后序
提交网址

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

struct node{
	char c;
	node *l,*r;
	node(char c):c(c){}
};

node* make(string pre,string in)
{
	if(pre.size()>0 && in.size()>0){
		char c = pre[0];
		node *p = new node(c);
		int i = in.find(c);
		p->l = make(pre. substr(1,i), in.substr(0,i));
		p->r = make(pre.substr(i+1), in.substr(i+1));
		return p;
	}
	return NULL;
}

void pos(node* root)
{
	if(root){
		pos(root->l);
		pos(root->r);
		cout << root->c;
	}
}

int main()
{
	string pre,in;
	while(cin >> pre >> in){
		node* root = make(pre,in);
		pos(root);
		cout << endl;
	}
	return 0;
}

二. 二叉排序树

1. 二叉排序树的构造与查找

题目链接

#include<iostream>
using namespace std;
struct node{
	int value;
	node *l,*r;
	node(int v):value(v),l(NULL),r(NULL){}  //刚开始忘记了初始化为NULL 
};

void insert(node* &root,int v)
{
	if(root == NULL){
		root = new node(v);
	}
	else{
		if(v > root->value) 
			insert(root->r,v);
		else
			insert(root->l,v);
	}
}

void pre(node* p,int v,int father)  //该函数也可以写到insert里 
{
	if(p){
		if(p->value == v){
			cout << father << endl;
			return;
		}
		pre(p->l,v,p->value);
		pre(p->r,v,p->value);
	}
}

int main()
{
	int n,v;
	while(cin >> n)
	{
		node *root = NULL;
		for(int i=0;i<n;i++){
			cin >> v;
			//此处最好用递归,如果用while向下寻找有些麻烦
			insert(root,v); 
			pre(root,v,-1); //根结点指针、待查找的值、父亲值 
		}
	}
}

三. 优先队列

1. 优先队列的基本使用

题目链接
题很水,只需知道优先队列应用于求解顺序问题,优先级高的位于队列最前。
还有一个要注意的是:重载运算符一定要加const!!而且要写在括号外面!!否则会像没定义比较函数一样报错,原因可能是因为const类型对象无法在const对象上使用。

#include<iostream>
#include<queue>
#include<string>
using namespace std;

struct complex{
	int real,ima;
	complex(int r,int i):real(r),ima(i){}
	bool operator < (complex o) const{  //重载运算符,注意const的使用及其位置
		return real*real+ima*ima < o.real*o.real+o.ima*o.ima; 
	}
};

int main()
{
	int n;
	while(cin >> n){
		priority_queue<complex> q;
		while(n--){
			string s;
			cin >> s;
			getchar();
			if(s == "Pop"){
				if(q.empty()){
					cout << "empty" << endl;
				}
				else{
					complex t = q.top();
					q.pop();
					cout << t.real<< "+i" << t.ima << endl;
					cout << "SIZE = " << q.size() << endl;
				}
			}
			else{
				int r,i;
				char c;
				cin >> r >> c >> c >> i;
				q.push(complex(r,i));
				cout << "SIZE = " << q.size() << endl;
			}
		}	
	}
}

2. 哈夫曼树

n个带有权值的结点构成的哈夫曼树可能不唯一,所以有关哈夫曼树的机试题往往考察的是求解最小带权路径长度和。使用优先队列,可以高效的求出集合中权值最小的两个元素,此时需要的是优先级最小的元素。
求哈夫曼
权值

搬水果

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

int main()
{
	int n,t;
	int a[1002];
	while(cin >> n){
		priority_queue<int,vector<int>,greater<int> > q;
		//优先队列默认less<T>,即递减。若要改成递增,则需要将三个参数都给出
		//三个参数分别为:存储对象类型,存储元素的底层容器,compare函数对象
		for(int i=0;i<n;i++){
			cin >> t;
			q.push(t);
		}
		int res=0;
		while(q.size()>1){  //取出两个再放进去一个
			int t1 = q.top();
			q.pop();
			int t2 = q.top();
			q.pop();
			q.push(t1 + t2);
			res += t1 + t2;
		}
		cout << res << endl;
	}
}

四. 散列表

1. 散列表的基本使用

魔咒词典
对于双向映射,当然可以用两个map分别存储key和value。
但如果任何key均不会等于value的情况下,可以直接存在一个map中。即:

mp[key] = value;
mp[value] = key;

2. 子串计算

题目链接
只需想到遍历子串的方法,在哈希表上加一即可。

for(int i=0;i<s.length();i++){
	for(int j=i;j<s.length();j++){
		string sub = s.substr(i,j-i+1); 
		mp[sub]++;
	}
}

3. 结合vector

谁是你的潜在朋友

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

int main()
{
	int n,m;
	while(cin >> n >> m){
		vector<int> v;
		int hash[300] = {0};
		for(int i=0;i<n;i++){
			cin >> m;
			hash[m]++; 
			v.push_back(m);
		}
		vector<int>::iterator it;
		for(it=v.begin();it!=v.end();it++){
			int res = hash[*it]-1;
			if(res == 0)
				cout << "BeiJu" << endl;
			else
				cout << res << endl;
		}
	}
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值