题型一:按照序号划分
将一个带头节点的单链表A分解为两个带头节点的单链表A和B,使得A表中含有原表中序号为奇数的元素,而B表中含有原表中序号为偶数的元素,且保持相对顺序不变。
思想:申请一个链表B,将偶数序号的节点摘下来,利用尾插法插入到链表B;将奇数序号的节点摘下来,尾插到链表A。
代码:
LinkList splitAtoAB(LinkList &A){
LinkList B = (LNode*)malloc(sizeof(LNode));
B->next=NULL;
LNode *p=A,*q=A->next,*r=B;//p为表A的尾节点,q用来处理子表,r为表B的尾节点
int s=1;//用来判断是奇还是偶节点
while(q!=NULL){//子表不为空
if(s%2==0){//偶数节点时,放到B表
r->next=q;
r=q;
}else{//奇数节点放到A表
p->next=q;
p=q;
}
q=q->next;//向后遍历
s++;
}
//尾节点置空
p->next=NULL;
r->next=NULL;
return B;
}
时间复杂度O(n);空间复杂度O(1)
题型二:按照节点中的元素划分
将一个带头节点的单链表A分解为两个带头节点的单链表A和B,使得A表中含有原表中节点数为奇数的元素,而B表中含有节点数为偶数的元素,且保持相对顺序不变。
思想:申请一个链表B,将偶数节点的节点摘下来,利用尾插法插入到链表B;将奇数节点序号的节点摘下来,尾插到链表A。
代码:
LinkList splitAtoAB(LinkList &A){
LinkList B = (LNode*)malloc(sizeof(LNode));
B->next=NULL;
LNode *p=A,*q=A->next,*r=B;//p为表A的尾节点,q用来处理子表,r为表B的尾节点
while(q!=NULL){//子表不为空
if(q->data % 2 == 0){//节点中的数据为偶数时,放到B表
r->next=q;
r=q;
} else{//节点中的数为奇数时放到A表
p->next=q;
p=q;
}
q=q->next;//向后遍历
}
//尾节点置
p->next=NULL;
q->next=NULL;
retuen B;
}
时间复杂度O(n);空间复杂度O(1)
奇偶链表相关题目:
设C={a1,b1 ,a2, b2,., an,bn}为线性表,采用带头结点的单链表存放,设计一个就地算法,将其拆分为两个线性表,使得A={a, a2, an} B={bn,...b2,b2);
思想:A链表采用尾插法,B链表采用头插法。将偶数序号的节点摘下来,利用头插法插入到链表B;将奇数序号的节点摘下来,尾插到链表A。
代码:
LinkList splitAtoAB(LinkList &A){
LinkList B = (LNode*)malloc(sizeof(LNode));
B->next=NULL;
LNode *p=A,*q=A->next,*r;//p为表A的尾节点,q用来处理子表,r为表B的尾节点
int s=1;//用来判断是奇还是偶节点
while(q!=NULL){//子表不为空
if(s%2==0){//偶数节点时,放到B表,利用头插法
r=q->next;
q->next=B->next;
B->next=q;
q=r;
}else{//奇数节点放到A表
p->next=q;
p=q;
q=q->next;//向后遍历
}
s++;
}
//尾节点置空
p->next=NULL;
return B;
}
时间复杂度O(n),空间复杂度O(1)