一、序言
- 在学习数据结构时,要经常思考一下:课程的目标是什么?(解决什么问题)
- 解决这些问题的方法是什么? (是系统的方法还是一门技术)
- 有哪些实际应用? (如何运用这些理论和方法解决其他的问题)
- 了解一下数据结构课程的起点:
二、思考题
-
题目:100桶饮料,其中一桶混有有害物体,用若干自愿者试验,每个自愿者可以尝试一桶或者多桶饮料,自愿者喝到有害饮料后2小时会发生恶心、出虚汗等反应,恶心持续20分钟后自然消失。三个小时内需要找到有害物体的桶,问至少要多少名自愿者?
分析过程:
假设编号为 100 桶用1到 100 个整数编号,这个编号可以用二进制表示,需7位二进制表示,2的7次方=128>100,如1号桶是二进制 0000001,5 号桶是 0000101…找 7个志愿者,对应桶二进制的由高到低编号,如 a,b,c,d,e,f,g。a 对应二进制的最高位,g对应二进制的最低位,每个志愿者分配一个杯子。
计算过程:
分别从 1-100 个桶中取出饮料(多少没关系,并没有说需要多少饮料才能引起不适反应)如第1号桶二进制是 0000001,只给g 杯中倒饮料,也即二进制位1的对应志愿者才分配饮料,5 号桶是 0000101,则需给 e 和g 杯中倒饮料(注意: 每次分配饮料是可以混合累加在
起的,不需要另外的杯子)。
100 个桶分配完毕,每个志愿者喝完杯中饮料后 20 分钟,看志愿者中那几个有反应,比如说如果 c,e,g 有反应,则7位志愿者对应的二进制为:0010101(有反应的志愿者对应的二进制位 1,其他为 0,转化为十进制,就是质量有问题的桶编号),0010101 的十进制是 21,则21 号桶质量有问题。 -
求n个数的最大值、次最大值。
方法:扫描一次所有元素,找出最大值,在剩下的元素中再通过扫描的方法找最大值
1)找最大值:
void max12(int a[], int n)
{
int maxl=a[0], max2,i, k, temp;
for(i=1; i<=n;i++){
if(a[i]>max1){
max1=a[i];
k=i;
}
temp=a[0];
a[0]=max1;
a[k]=temp;
}
max2=a[0];
for(i=2; i<=n;i++){
if(a[i]>max2){
max2=a[i];
k=i;
}
temp=a[1];
a[1]=max2;
a[k]=temp;
}
}
一共比较了n-1(上面那个循环)+n-2(下面那个循环)次,共2n-3次。
2)找次最大值:
次最大值可能出现的地方一定是与最大值直接进行比较过的(这个地方可能不太好直接理解,打个比方,就好比亚军只会输给冠军),即打星号的数,再把打星号的数保存,得到7,4,8,共有3个,即k=3,我们发现 k=log n(以2为底)。故找最大值和次大值共需n-1+log n-1(以2为底)=n+log n-2(以2为底)次比较。
- 判断一个表达式中括号是否匹配:
//将这个表达式看成一个字符串
void match(char *ch){
int count=0,i=0;
while(ch[i]!=';'){
if(ch[i]=='('){
then count++;
}
else if(ch[i]==')'){
then count--;
}
}
if(count!=0){
then printf(%s\n,"no match");
}
else{
printf(%s\n,"match");
}
}