1.给定两个单链表的头指针分别为head1和head2,请设计一个算法判断这两个单链表是否相交,如果相交则返回第一个交点,要求算法的时间复杂度为O(length1+length2),其中length1和length2分别为两个链表的长度。
思路:先各遍历一次得到链表长度得到长度差为d,让长的链表先走d个结点,然后两个链表同步遍历找到共同结点。
typedef struct node
{
int data;
struct node *next;
}*node;
node Find_Node(node head1,node head2)
{
int len1,len2,d;
node longList,shortList,p;
int n=0;
p=head1;
while(p!=NULL)
{
n++;
p=p->next;
}
len1=n;
n=0;
p=head2;
while(p!=NULL)
{
n++;
p=p->next;
}
len2=n;
if(len1>len2)
{
longList=head1;
shortList=head2;
d=len1-len2;
}
else
{
longList=head2;
shortList=head1;
d=len2-len1;
}
while(d!=0)
{
longList=longList->next;
d--;
}
while(longList!=NULL)
{
if(longList==shortList)
return longList;
else
{
longList=longList->next;
shortList=shortList->next;
}
}
return NULL;
}
2.统计二叉树各层中独生叶结点(既是叶结点又无兄弟结点)的数目。
要求:编写函数LeafNoBrotherInEachLevel(root),其中root为指向某二叉树根结点的指针,该函数的功能是输出以root为根的二叉树各层中独生叶结点的数目。
思路:采用层次遍历,若根为空,输出0层0个;根为叶结点,输出0层1个;
根不空且非叶结点,输出0层0个,设置level=1来记录下一层的独生叶结点,根结点入队。
对于当前层的所有结点,首先判断其孩子结点是否是独生叶结点并计数,然后,将其孩子入队。这一层遍历完后,输出其下一层的独生叶结点数目。最后一层就不用输出了其下一层了。
typedef struct node
{
int data;
struct node *left,*right;
}*Tree;
void LeafNoBrotherInEachLevel(Tree root)
{
if(root==NULL){ //根为空
printf("0层0个\n");
return;
}
if(root!=NULL&&root->left==NULL&&root->right==NULL)//根为叶结点
{
printf("0层1个\n");
return;
}
printf("0层0个\n");
int level=1;//level为下一层的层数
int front=-1,rear=-1,count,n;
Tree queue[maxsize];
queue[++rear]=root;//根结点入队
while(front!=rear)
{
count=0;//记录下一层的独生叶结点
n=rear-front;//当前层的结点个数
for(int i=0;i<n;i++)
{
Tree p=queue[++front];//出队
if(p->left!=NULL&&p->right==NULL)
if(p->left->left==NULL&&p->left->right==NULL)
count++; //左孩子为独生叶结点
if(p->left==NULL&&p->right!=NULL)
if(p->right->left==NULL&&p->right->right==NULL)
count++;//右孩子为独生叶结点
//左右孩子入队
if(p->left!=NULL)queue[++rear]=p->left;
if(p->right!=NULL)queue[++rear]=p->right;
}
if(front!=rear)//不是最后一层就输出下一层的独生叶结点数目
printf("%d层有%d个独生叶结点\n",level++,count);
}
}