個人準備複試上機時,遇到的題,方便之後鞏固
上機練習題型
全排列
運用遞歸方法,對n個數進行全排列:
(若要求對n個字母進行全排列,p[]類型可改爲char,原代碼中p[index]=i可改爲p[idex] = i+‘a’-1或p[index] = i+‘A’-1)
#include<iostream>
using namespace std;
const int maxn = 11;
//p爲當前排列,hashTable記錄整數x是否已經在p中
int nn,p[maxn],hashTable[maxn] = {false};
//當前處理排列的第index位
void generateP(int index){
int i= 1;
if(index == nn+1){//遞歸邊界,已經處理完排列的1~n位
for(i = 1;i<=nn;i++){
cout<<p[i]; //輸出全排列
}
cout<<endl;
return ;
}else{
for(i = 1;i<=nn;i++){
if(hashTable[i]==false){ //處理不在p中的
p[index] = i; //i加入當前序列
hashTable[i] = true; //修改標記
generateP(index+1); //處理第index+1位
hashTable[i]=false; //遞歸的下邊處理完了,返回到這裏,還原狀態
}
}
}
}
int main(){
nn = 3;
generateP(1); //從1開始
return 0;
}
哈夫曼樹最小帶權路徑
輸入:
4
1,1,1,1
輸出:最小帶權路徑
大體思路:建立小頂堆,將輸入的頂點入堆,再每次取出堆中兩個最小的元素即堆頂,作爲左右孩子節點,將他們的和作爲雙親,再放回堆中,如此反覆。直到堆中只剩一個節點。
#include<iostream>
#include<queue>
using namespace std;
priority_queue<int,vector<int>,greater<int> > que;//優先隊列.小頂堆
void main20192(){
char a;
int n,i = 0,num;
while(cin>>n){
while(que.empty()==false)que.pop();//清空堆中元素
//輸入 以,隔開
for(i=1;i<=n;i++)
{
cin>>num;
que.push(num);
if(i!=n)cin>>a;//吸收最後一個回車
}
int sum = 0;
while(que.size()>1){
//取出堆中兩個最小的元素,作爲同一節點的左右孩子,且雙親的權值是他們的和
int a = que.top();
que.pop();
int b = que.top();
que.pop();
sum += a+b;//該父親節點必爲非葉子結點,累加
que.push(a+b);//雙親的權值放回堆中
}
cout<<sum<<endl;
}
}
int main(){
main20192();
return 0;
}
已知先序序列,中序序列求後序序列
先序的第一個字符爲根節點,再去中序中找根節點的位置,並以此切分,得到左右子樹的序列。左右子樹再同理。此方法並沒有建立出樹,只是對字符串的劃分
#include<iostream>
#include<string>
using namespace std;
typedef struct BTNode{
char val;
struct BTNode *left;
struct BTNode *right;
}BTnode;
int index = 0;
//核心代碼
void getTree(string front,string mid){
if(mid.length() == 0)
return ;
char root = front[index ++];//index每次遞歸加一,用以獲取先序中的下一個根字符
int i = mid.find(root); //找到根在中序中的位置
//切分中序序列,得到左右兩部分
string left = mid.substr(0,i);
string right = mid.substr(i+1,mid.length()-1);
//後序遍歷:左右根
getTree(front,left); //繼續遞歸左邊
getTree(front,right); //遞歸右邊
cout<<root;
}
void wangdao3334(){
string front;
string mid;
cout<<"先序遍歷:";
cin>>front;
cout<<"中序遍歷:";
cin>>mid;
getTree(front,mid);
}
int main(){
wangdao3334();
return 0;
}
求一個數的m進制
#include<iostream>
using namespace std;
/** 輸入num1,num2,求和的m進制,m<=16 */
void wangdao4342(){
char num[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
int m,num1,num2;
cin>>m>>num1>>num2;
int sum = num1+num2;
char a[10],index = 0;
while(sum!=0){
a[index ++] = num[sum%m];//餘數。主要是爲了處理餘數大於10的情況
sum /= m; //繼續求下一位
}
for(m = index-1;m>=0;m--){
cout<<a[m]; //倒着輸出
}
cout<<endl;
}
int main(){
wangdao4342();
return 0;
}