宁大916数据结构
20年算法设计题
- 计算一棵二叉树中包含的叶子结点的总数
int CalCount(BiTree T){
int leftsum,rightsum;
if(T==NULL)
return 0;
leftsum = CalCount(T->lchild);
rightsum = CalCount(T->rchild);
return leftsum+rightsum+1;
}
- 某大学组织 n 个学生去多家单位实习,如果所有单位总共可以提供 m 个实习岗位,实习生和实习单位经过洽谈后双方自愿进行,校方则希望能够达到实习人数最大化。假设双方彼此只有愿意和不愿意,没有优先程度考虑,试采用合适的二分图结构表示该过程,并设计合理的算法实现二分图的最大匹配,达到实习人数最大化。
//本质上就是匈牙利算法问题,类似的还有男女匹配
int line[n][m]; //line[i][j]=1表示实习生i和实习单位j双方愿意
int used[n];
int nxt[m];
//遍历每一个实习生
int match(){
int sum = 0;
for(int i=0;i<n;i++)
used[i] = 0;
if(Find(i))
sum++;
return sum;
}
bool Find(int x){
for(int i=1;i<=m;i++)
if(line[x][i] == 1 && !used[i]){
used[i] = 1;
if(nxt[i] == 0 || Find(nxt[i])){
nxt[i] == x;
return true;
}
}
return false;
}
19年算法设计题
- 将中缀表达式转化为后缀表达式,并计算表达式的值
- 这一题《算法笔记》中有,但是代码太长了。描述算法思想好了。
- 算法思想分为两个步骤:
1.先将中缀表达式转为后缀表达式
2.计算后缀表达式
- (1) 中缀表达式转后缀表达式:
- 设立一个操作符栈,用以临时保存操作符;设立一个数组,用以存放后缀表达式。
- 从左向右扫描表达式,如果遇到操作数,就把操作数加入后缀表达式数组中。
- 如果遇到操作符op,就把其优先级和操作符栈的栈顶元素操作符的优先级进行比较:
- 若op的优先级高于栈顶操作符优先级,则入栈。否则,则将操作符栈的元素不断弹出到后缀表达式数组中,直到op的优先级高于栈顶操作符的优先级为止。
- 重复上述操作,直到中缀表达式全部扫描完毕,之后操作符栈若仍有元素,则依次弹出到后缀表达式数组中。
- (2) 计算后缀表达式
- 从左向右扫描后缀表达式,如果是操作数,则入栈。如果是操作符,则连续弹出两个操作数,然后进行操作符的操作运算,生成的新操作数入栈。反复直到后缀表达式扫描完毕,这时栈中只存在一个数,就结果答案。
- 求一棵给定二叉树中结点值为x的结点个数 (x不唯一)
//法一
int CalCount(BiTree bt,int x){
int n=0;
if(bt==NULL)
return 0;
if(bt->data ==x)
n=1;
return (CalCount(bt->lchild,x)+CalCount(bt->rchild,x)+n);
}
//法二
void CalCount(BiTree bt,int x,int &n){
if(bt==NULL)
return;
if(bt->data==x)
n+=1;
CalCount(bt->lchild,x,n);
CalCount(bt->rchild,x,n);
}
- 递归实现二路归并排序
void mergeSort(int a[],int left,int right){
if(left<right){
int mid = left+(right-left)/2;
mergeSort(a,left,mid);
mergeSort(a,mid+1,right);
Merge(a,low,mid,high);
}
}
void Merge(int a[],int low,int mid,int high){
int i=0,j=0,k=0;
//辅助数组b[n],用于存放a[n]中的所有元素
for(i=low;i<=high;i++)
b[i] = a[i];
//比较b的左右两段中的元素,将较小值复制到a[]中
for(i=low,j=mid+1,k=i; i<=mid && j<=high; k++){
if(b[i]<=b[j])
a[k] = b[i++];
else
a[k] = b[j++]
}//for循环结束
while(i<=mid)
a[k++] = b[i++];
while(j<=high)
a[k++] = b[j++];
}