一、举例说明二分查的基本思想,并用类C语言设计算法实现二分查(折半查)。
解:二分法查的过程是:首先确定待查记录的范围,然后逐步缩小范围到直到到或不到该记录为止。例如:已知11个数据元素的有序表,(关键字为数据元素的值):(05,13,19,21,37,56,64,75,80,88,92),现在查关键字为21的数据元素。设指针low指向下界,high指向上界,mid=(low+high)」/2指向中间区域。所以此例种设low=1,则high=11,mid=6。首先取mid所指元素ST.elem[mid].key与给定值k ey=21比较,因为56>21,说明所查key=21一定在56的左侧,则令high=mid-1,所以所查元素在[low,mid-1]之间即[1,5]范围,求出mid=(low+high)」/2=3,取mid所指元素19再与k e y的值21比较,因为19<21,所以所查元素必在21的右侧,则令low=mid+1,所以所查元素在[mid+1,high]之间即[4,5]范围,求mid=(low+high)」/2=4,取mid所指元素21再与k ey 的值21比较,相等,查成功,所查元素在表中序号为mid的值是4。按照以上方法若所查元素在表中不存在,则会出现low>high的情况,因此当low>high说明查不成功。
算法如下:
Int Search_Bin(SSTable ST, KeyType key)
{
/
/在有序表ST中查值为ke y的元素,若到,则函数值为该元素在表中的位置,否则为0 low=1;high=ST.length;//置区间初值
while(low<=high)
{
mid=(low+high)/2; //中间位置
if(EQ(key,ST.elem[mid].key) returnmid; //到返回元素在表中的位置
else if (LT(key, ST.elem[mid].key)) high=mid-1; //继续在前半区间
else low=mid+1; //继续在后半区间
}
Return0; //顺序表中不存在待查元素
} //二分法查算法
二、将两个有序单链表合并为一个有序单链表
通过比较不断后移指针合并链表。
void MergeLi st_L (LinkLis t &La,LinkLis t &Lb,LinkLis t &Lc)
{//已知单链表La和Lb的元素按非递减排序,合并两表得到非递减排序的表L c
pa = La->next ;pb = Lb->next ;//分别指向第一个结点
Lc = pc = La ;//用La的头节点作为Lc的头节点
while ( pa && pb ) {
if ( pa->data <= pb->data ) {
pc->next = pa ;pc = pa ;pa = pa->next ;}
else { pc->next = pb ;pc = pb ;pb = pb->next ;}
}
pc->next = pa ? pa : pb ;//处理剩余部分
free (Lb) ;
}
三、假设表达式由单字母变量和双目四则运算符(+,-,*,/)构成,用类C语言设计算法将一个通常书写形式且书写正确的表达式转换为逆波兰式。
void Change(char* s1, char* s2)
//将字符串s1中的中缀表达式转换为存于字符串s2中的后缀表达式
{
Stack R; //定义用于暂存运算符的栈
InitSta ck(R); //初始化栈
Push(R,'@'); //给栈底放入'@'字符,它具有最低优先级0
int i,j;
i=0; //用于指示扫描s1串中字符的位置,初值为0
j=0; //用于指示s2串中待存字符的位置,初值为0
char ch=s1[i]; //ch保存s1串中扫描到的字符,初值为第一个字符
while(ch!='@')
{ //顺序处理中缀表达式中的每个字符
if(ch=='+'||ch=='-'||ch=='*'||ch=='/')
{ //对于四则运算符,使暂存在栈中的不低于ch优先级的运算符依次出栈并写入到s2中
char w=top(R);
while(Precede nce(w)>=Precede nce(ch))
{ // Precedence(w)函数返回运算符形参的优先级
s2[j++]=w; Pop(R); w=top(R);
}
Push(R,ch); //把ch运算符写入栈中
ch=s1[++i];
}
else
{ s2[j++]=ch;ch=s1[++i];}
}
//把暂存在栈中的运算符依次出栈并写入到s2串中
while(!Empty(R))
{ s2[j++]=pop(R); }
s2[j++]='\0';
}
求运算符优先级的Prece dence函数为:
int Precede nce(char op)//返回运算符op所对应的优先级数值
{ switch(op)
{
case '+': case '-':
return1; //定义加减运算的优先级为1
case '*':case '/':
return2; //定义乘除运算的优先级为2
case '@': case ‘(’:
return0; //定义在栈中的左括号和栈底字符的优先级为0 }
}
四、设二叉树以二叉链表形式存放。设计非递归算法,实现二叉树的中序遍历。
算法如下:
StatusInorder T ranve rse(BiTreeT,status(*visit)(TELemType e))
{//采用二叉链表存储,visit是对数据元素操作的应用函数,中序非递归算法
c语言搜题软件推荐IniStac k(S);p=T;
while(p||!StackEm pty(S)){
if (p){Push(S,p);p=p->lchild;}//根指针进栈,遍历左子树
else {//根指针退栈,遍历右子树
Pop(S,p);if(!visit(p->data))returnERROR;
p=p->rchild;
}
}
ReturnOK;
}
五、设二叉树以二叉链表形式存放。利用循环队列,用类C语言设计算法实现二叉树的按层次遍历。
算法:
typedef structBiTnode{/*用二叉链表存储二叉树*/
TElemTy pe data;
structBiTnode *lchild,*rchild;
}BiTnode,*BiTree;
StatusInOrder Traver se(BiTreeroot, Status(*visit)(TElemTy pe 2)){//层次遍历算法
InitSta ck(S);// 初始化栈空间
BiTNode* p = root;
while(p!=NULL||!StackEm pty(S)){ /*不是空树*/
if(p) { Push(S,p); p = p->lchild;}
else{
Pop(S,p);
Visist(p->data);
p=p->rchild;
}/*else*/
}/*while*/
returnOK;
}/*InOrder Traver se*/
六、(1)什么是完全二叉树?(2)画出6个顶点的完全二叉树。(3)设二叉树以二又链表形式存放,用类C语言设计算法判断一棵二又树是否为完全二叉树。
(1)深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中的编号从1到n一一对应时,称为完全二叉树。
(2)略
(3)int iscompl etetre e(BiTree&T,LinkQue ue &Q)
//是完全二叉树返回1,否则返回0、
{
BiTreep; p=T;
if(!T) return1;
initque ue(Q); enqueue(Q,T);
while(!queueem pty(Q))
{ dequeue(Q,p);
if(p) { enqueue(Q,p->lchild); enqueue(Q,p->rchild); }
if(!p)
{ while(!queueem pty(Q))
{ dequeue(Q,p);
if(p) //空节点后还有节点
{ return0; }
}
} } return1;}
七、基于图的广度优先搜索策略,设计算法判别以邻接表方式存储的有向图中是否存在由顶点vi到vj的路径(ij)。注意,算法中涉及的图的基本操作必须在此存储结构上实现。
int BFSTrav erse_p ath(ALGraph G,int i,int j)
{
for ( v = 0; v < G.vexnum; ++v ) visited[v] = FALSE;
InitQue ue(Q);/* 访问I,起始顶点入队*/
visited[i] = TRUE;
EnQueue(Q, i);
while( !QueueEm pty(Q) )
{/* 出队,访问出队元素的邻接点*/
DeQueue(Q,i);
for ( k = FirstAd jVex(G,i);k>=0;k=NextAdj Vex(G,i,k) )
if ( !visited[k] )
{/* 访问顶点u的尚未访问的邻接点并入队*/
if(k==j) return1;//有路径
visited[k] = TRUE;EnQueue(Q, k);
}}return0;//无路径
}
八、基于图的深度优先搜索策略,设计算法判别以邻接表方式存储的有向图中是否存在由顶点vi到vj的路径(ij)。注意,算法中涉及的图的基本操作必须在此存储结构上实现。
int DFSPath(Graph G, int v, int w)
{//如果v到w有路径返回1,否则返回0;
G为有向图的邻接表
for (int vi = 0; vi < G.vexnum; ++vi )visited[vi] = FALSE;
visited[v]=TRUE;
for(vi=FirstAd jVex(G,v);vi>=0;vi=NextAdj Vex(G,v,vi))
{ if(!visited[vi])
{ visited[vi]=1;
if(vi==w) return1; //到路径
else {return(DFSPath(G,vi,w)) ;
}
}
return0;
}
九、设二叉排序树以二叉链表形式存放,设计非递归算法判断二叉排序树中是否存在值为X
的结点,若存在,返回其地址,否则返回空指针。
typedef structBiTnode{/*用二叉链表存储二叉树*/
int data;
structBiTnode *lchild,*rchild;
}BSTnode,*BSTree;
BSNode* InsertB ST(BSTreeTptr,KeyType key)
{
BSTNode *f,*p=TPtr; //p的初值指向根结点
while(p){ //查位置
if(p->key==key) returnp;//到key,返回其地址
p=(p->key>key)?p->lchild:p->rchild;
//若p->key>key,则在左子树中查,否则在右子树中查
} //endwhil e
return0;
} //InsertB ST
十、(1)什么是二叉排序树?(2)设二叉排序树以二叉链表形式存放设计算法,从大到小输出给定二叉排序树中结点值不小于k的数据元素。
(1)二叉排序树或者是一棵空树;或者是具有下列性质的二叉树:若他的左子树不空,则左子树上所有的结点的值均小于他的根结点的值;若他的右子树不空,则右子树上所有的结点的值均大于他的根结点的值;他的左右子树也分别是二叉排序树。
(2)算法如下:
typedef structBiTnode{/*用二叉链表存储二叉树*/
TElemTy pe data;
structBiTnode *lchild,*rchild;
}BiTnode,*BiTree;
StatusVisitKe y(BiTreeroot, TElemTy pe key){
//通过右根左遍历顺序依次输出结点值,遇到小于给定k ey值的节点停止
InitSta ck(S);// 初始化栈空间
BiTNode* p = root;
while(p!=NULL||!StackEm pty(S)){ /*不是空子树*/
if(p) { Push(S,p); p = p->rchild;}
else{
Pop(S,p);
if(p->data>=key)
{ printf("%c",q->data);
q=q->lchild;
}
else break;
}/*else*/ }/*while*/
Destroy Stack(S);//释放栈空间
returnOK;
}/*InOrder Traver se*/
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论