已知非空线性链表第1个链结点的指针为list,在算法的设计中需要用到4个LinkList指针,q 用来记录域值最大的那个链结点,s 用来记录域值最大的那个链结点的直接前驱结点,p用来遍历整个链表,r 用来记录在遍历过程中当前正在比较的链结点的直接前驱结点。在算法设计中需要分两步,第一步是要找到最大值结点,第二步是要将最大值结点移动至链表的末尾(如果最大值结点不是末尾结点)。
在将最大值结点移动到末尾结点的算法中,需要考虑最大值结点是否是链表的第1个结点,因为最大值是否是链表第1个链结点对最大值结点移动到末尾的过程有影响。链表定义如下:
typedef struct node {
char data[100];
struct node *link;
}LNode, *LinkList;
算法设计如下:
/*将非空线性链表中数据域值最大的那个链结点移至链表的末尾
q用来指向最大值结点的地址,最开始假定第一个结点为域最大值结点,p用来遍历链表,
r用来在遍历过程中所比较值域链结点的直接前驱结点,s用来记录最大值域节点的直接前驱结点*/
void removeElemToEnd( LinkList *list ){
LinkList q = *list, p = ( *list )->link, r = *list, s;
while( p != NULL ){ //寻找最大值结点及其前驱结点
if(strcmp( p->data, q->data ) > 0){ //如果新的链结点大于之前记录的域最大结点,则更新s, q的值
s = r;
q = p;
}
r = p; //如果新的链结点不大于之前记录的域最大结点,则跳到下一个链结点
p = p->link;
}
if( q != r ){ //如果最大值结点不是链表的末尾结点
if( q == *list ){ //如果最大值结点是链表的第一个结点
*list = ( *list )->link;
}
else{ //如果最大值结点不是链表的第一个结点
s->link = q->link;
}
r->link = q; //将最大值结点移动至末尾,并将新的末尾结点的指针域置空
q->link = NULL;
}
}