题1:
某带头结点的非空单链表L中所有元素为整数,结点类型定义如下:
typedef struct node
{ int data;
struct node *next;
} LinkNode;
设计一个尽可能高效的算法,将所有小于零的结点移到所有大于等于零的结点的前面。
分析:
定义一个p指针指向L->next,一个pre指向头结点(也就是p指针的前驱)。
该题可以使用while循环先找到第一个小于0的数(其实这一步也可以不要,因为后面那个while也可以做到,不过这里为了方便理解,所以就加上了),然后再使用while循环将该小于0的结点在原位置删除,将其插入到头结点后面(其实这里就有点像单链表的头插法),然后指针指回pre的next,进行比较,大于0就跳过,往后查找,小于0就按上面的规则进行删除,然后使用头插法插入头结点后面,直到所有结点都处理完毕。
void Move(LinkNode *&L)
{ LinkNode *p=L->next,*pre=L;
while (p!=NULL && p->data<0) //跳过小于0的结点
{ pre=p;p=pre->next;
}
while (p!=NULL)
{ if (p->data<0) //若*p结点值小于0
{ pre->next=p->next; //从链表中删除*p结点
p->next=L->next; //将*p结点插入到头结点之后
L->next=p;
p=pre->next; //p指向*pre之后结点,pre不变
}
else //若*p结点值不小于0
{ pre=p; //pre、p同步后移一个结点
p=p->next;
}
}
}
题2:
假设二叉树中有n个结点,每个结点值为单个字符,而且所有结点值均不相同,采用二叉链存储结构存储,其结点类型定义如下:
typedef struct node
{ char data;
struct node *lchild,*rchild;
} BTNode;
请完成以下任务:
(1)设计一个算法,在二叉树b中查找x结点(指结点值为x的结点),若找到该结点,返回其地址,否则返回NULL。
BTNode *Findx(BTNode *b,char x) //在二叉树b中查找x结点
{ BTNode *p;
if (b==NULL)
return NULL;
else
{ if (b->data==x)
return b;
p=Findx(b->lchild,x);
if (p!=NULL)
return p;
return Findx(b->rchild,x);
}
}
题3:
(2)设计一个算法,利用(1)小题设计的算法输出二叉树b中x结点的所有子孙结点值。
void Sons(BTNode *b,char x) //输出x结点的子孙,初始时b指向x结点
{ if (b!=NULL)
{ if (b->data!=x)
printf("%c ",b->data);
Sons(b->lchild,x);
Sons(b->rchild,x);
}
}
void OutSons(BTNode *b,char x) //输出二叉树b中x结点的所有子孙结点值
{ BNode *p= Findx(b,x);
if (p!=NULL)
Sons(p,x);
}