1.设计在单链表中删除值相同的多余结点的算法
注意点
- 值相同的节点不一定相邻=>采用中间指针s,使s始终与被删除指针相邻;
- 每一个值都需要遍历整个表=>双重循环 两个指针
核心代码
void delredundant(lklist *&head) {
lklist *p, *q, *s;
for (p = head; p != NULL; p = p->next) {
for (q = p->next, s = p; q != NULL; ) {
if (q->data == p->data) { // 如果发现重复节点
s->next = q->next; // 让前一个节点指向当前节点的下一个节点
free(q); // 释放当前节点的内存
q = s->next; // 更新当前节点为下一个节点
} else {
s = q; // 更新前一个节点为当前节点
q = q->next; // 更新当前节点为下一个节点
}
}
}
}
可以结合画图来理解
2.设有两个集合A和集合B,要求设计生成集合C=A∩B的算法,其中集合A、 B和C用链式存储结构表示
注意点
这道题与上一道题类似,都需要将链表遍历完。但是我们有两个表,因此我们需要寻找一个表a(b)为基准,每遇到a(b)中的一个节点,就遍历一遍表b(a);
核心代码
p
是指向链表 ha
的指针,用于遍历链表 ha
。
q
是指向链表 hb
的指针,用于遍历链表 hb
。
t
是一个临时指针,用于创建新节点。
hc
是新链表的头指针,它被初始化为 NULL
,表示新链表为空。
typedef struct node {int data;struct node *next;}lklist;
void intersection(lklist*ha,lklist *hb)
{
lklist *p,*q,*t;
lklist *hc=NULL;
for(p=ha;p!=0;p=p->next)
{ for(q=hb;q!=0;q=q->next)
if (q->data==p->data)
break;
if(q!=0){
t=(lklist*)malloc(sizeof(lklist));
t->data=p->data;
t->next=hc;
hc=t;
}
}
}
链表-二叉树
1.设计一个求结点x在二叉树中的双亲结点算法
描述:
在 preorder
函数中,我们使用了递归的方法来遍历二叉树。对于当前节点 bt
,我们首先检查当前节点是否为空,以及是否已经找到了节点 x
。如果当前节点不为空且尚未找到节点 x
,我们就检查当前节点的值是否等于 x
。如果等于,我们将 flag
置为 1,并立即返回。如果不等于,则继续递归地遍历当前节点的左右子树。
在找到节点 x
后,我们就可以确定其双亲节点。这时,我们维护了一个队列 q
,用于存储从根节点到当前节点的路径。具体来说,我们将遍历过的每个节点都加入队列 q
中。然后,我们从队列中查找节点 x
的双亲节点。
在函数 parent
中,我们调用了 preorder
函数来遍历二叉树并找到节点 x
。接着,我们从队列 q
中遍历节点,查找节点 x
的双亲节点。对于每个节点,我们检查其左右子树是否包含节点 x
。如果找到了包含节点 x
的子树,则当前节点就是节点 x
的双亲节点。
最后,我们根据找到的双亲节点或未找到的情况,输出相应的结果。
核心代码
typedef struct node {
int data;
struct node *lchild,*rchild;
} bitree;
bitree*q[20];
int r=0,f=0,flag=0;
voidpreorder(bitree *bt, char x){
if (bt!=0 && flag==0)
if(bt->data==x) {
flag=1; return;
}
else{
r=(r+1)% 20;
q[r]=bt;
preorder(bt->lchild,x);
preorder(bt->rchild,x);
}
}