双向循环链表>0前移,<0 后移
题目
已知带头几点的双向循环链表头结点为list,除头结点外每个结点的数据域为整型,请写一算法,将链表中所有数据域大于0的结点放在小于0的前面。若链表中除头结点以外其他的为空,这返回0,否则,返回1.
代码
第一种
需要移动指针,即直接将>0的数据移动到list的后继结点,
缺点:频繁修改指针。
// > 0 前移 ,<0 后移
int PRINT(DLinklist list){
DLinklist p,q;
p=list->rlink;
if (p==list) {
return 0;
}
while (p!=list) {
if(p->data<0){
p=p->rlink;
}else {
q=p;
p->llink->rlink=p->rlink;
p->rlink->llink=p->llink;
p=p->rlink;
// 将结点插入到list后面
q->rlink=list->rlink;
q->llink=list;
list->rlink->llink=q;
list->rlink=q;
}
}
printf("\n");
p=list->rlink;
while (p!=list) {
printf("%d,",p->data);
p=p->rlink;
}
return 1;
}
第二种
直接交换数据域,不用移动指针,同时从链表的两边向中间靠近,思路有点像“快速排序”的思想。
// 双向循环链表>0前移,<0 后移
int PRINTVAL(DLinklist list){
DLinklist p=list->rlink,q=list->llink;
int temp;
if (p==list) {
return 0;
}
while (p!=q) {
while (p->data>0&&p!=list) {
p=p->rlink;
}
while (q->data<0&&q!=list) {
q=q->llink;
}
if (q->rlink!=p) {
temp = p->data;
p->data=q->data;
q->data=temp;
p=p->rlink;
q=q->llink;
if (q->rlink==p||(p==list&&q==list)) {
return 1; // 链表已满足条件,立马结束循环
}
}else {
return 1;
} // if
}// while
}
明显第二种相对第一种来说,时间复杂度要快好多。