1、一个带头结点的单链表A,其数据元素是字符字母字符、数字字符、其他字符,设计算法将A表分成三个带头结点的循环单链表A、B和C,分别含有字母、数字和其它符号的同一类字符,利用原表空间。
void split(LinkList &A){ // A是带头结点的的单链表,其数据元素是字符字母、字符、数字字符、其他字符。
LinkList p=A->next,pre,rearB,rearC; // p为工作指针,指向A表的当前元素,rearB,rearC分别为B,C的尾结点,为了最后变成循环链表
LinkList B=(LinkList)malloc(sizeof(LinkNode));
B->next=NULL; //准备循环链表B的头结点
rearB=B;
LinkList C=(LinkList)malloc(sizeof(LinkNode));
C->next=NULL; //准备循环链表C的头结点
rearC=C;
pre=A;
p=A->next;
while (p) { //算法思想是取出当前元素,根据是字母、数字或其它符号,分别插入(尾插法!!!!!因为需要有尾结点)相应表中。
if(p->data>='a'&&p->data<='z'|| p->data>='A'&&p->data<='Z'){ // 将字母字符插入A表
pre=p; //维持不变,继续访问下一个结点
p=p->next;
}
else if (p->data>='0'&&p->data<='9'){ // 将数字字符插入B表
pre->next=p->next; //取出p结点
rearB->next=p;
rearB=p; //重置rearB指针
p=pre->next; // 让p指向pre的后继,也就是下一个当前结点
}
else { // 将其它符号插入C表
pre->next=p->next; //取出p结点
rearC->next=p;
rearC=p; //重置rearC指针
p=pre->next; // 让p指向pre的后继,也就是下一个当前结点
}
}//while
pre->next=A; //形成单循环链表
rearB->next=B;
rearC->next=C;
}
2、设具有n个结点的完全二叉树采用顺序结构存储在顺序表BT[1..n]中,试编写非递归先序遍历算法。(设bt类型为datatype)
void PreOrder(datatype BT[]){ //传入数组
int i=1;
SeqStack S;
S=Init_SeqStack();
while(i<=n||!Empty_Stack(S)){
if(i<=n){
visit(BT[i]); //注意i是下标,要访问的是下标对应的结点
Push_SeqStack(S,i); //下标进栈
i=i*2; //访问左子树
}
else{
Pop_SeqStack(S,&i);
i=i*2+1; //访问右子树
}
}
}
3、编写算法实现带头结点的单链表作为存储结构的两个递增有序表La ,Lb进行如下操作:将所有在 Lb 表中存在而 La 表中不存在的结点插入到 La 中,其中 La 和 Lb 分别为两个链表的头指针。
void union(LinkList &La,LinkList &Lb){
LinkList pre=La;
LinkList pa=La->next;
LinkList pb=Lb->next;
while(pa&&pb){
if(pa->data<pb->data){
pre=pa;
pa=pa->next;
}
else if(pa->data>pb->data){
pre->next=pb;
pre=pb;
pb=pb->next;
pre->next=pa;
}
else{
pb=pb->next;
}
} //跳出循环要么pa为空,要么pb为空
if(pb){ //pb不为空(也就是pa为空跳出循环了),把pb链接到pa后面
pre->next=pb; //pre->next,不是pa->next!!!!!!!!!
}
//若pa不为空,pb为空则说明已经插入完成,不需要干什么了
}
4、设计一个算法,从具有n个顶点的无向图中删除一条边(u,v)。已知无向图采用邻接表方法存储,u和v分别是一条边对应的两个顶点的序号。
int DelEdge(ALGraph &G,int u,int v){ //在无向图G中删除边(u,v)
if(DeleteArc(G,u,v)&&DeleteArc(G,v,u)){ //均删除成功
G->edgeNum--;
return 1;
}
else return 0;
}
int DeleteArc(ALGraph &G,int u,int v){ //在u的边表中删除边表结点v
EdgeNode *s,*p;
s=G->adjlist[u].firstedge;
if((s)&&(s->adjvertex==v)){ //v是u的第一个邻接顶点
G->adjlist[u].firstedge=s->next; //不能写s=s->next,因为一会要free(s)
free(s);
}
else{
while((s)&&(s->next)&&(s->next->adjvertex!=v)){ //v不是u的第一个邻接顶点,在u的边表中查找v,并将其删除
s=s->next;
}
if((s->next==NULL)||(s==NULL)){
printf("无此边");
return 0;
}
else{
p=s->next;
s->next=p->next;
free(p);
return 1;
}
}
}
5、设计算法在二叉链表结构下二叉排序树bst中,求关键字K所在结点的层次。
int BstSearch(BSTree bst,KeyType k){
BSTree p=bst;
int n=0; //记录结点的层数
while(p!=NULL&&p->data!=k) { //p不为空,且未找到关键字为k的结点
if(p->data>k) p=p->lchild;
else p=p->rchild;
n++;
}
if(p==NULL) return (0); //直到p为空都未找到关键字为k的结点
return (n+1);
}