所有对链表的操作都是由最基本的几种操作进行组合:
当前节点强制使用p指,当前节点的前驱q,当前节点的后驱r,强制使用这种模式,形成范式。
1,摘下一个节点
q->next = p->next; p被摘下;
2,将pNew插入到p的位置
pNew->next = p;
q->next = pNew;
q = q->next;
3, 复位
保持q是p的前驱,不要乱了阵型。
比如这样一个场景:pHeadA, pHeadB是两个升序列表的头节点,现要求将这两个合并成一个降序的列表,并以pHeadA为投节点。
pOldHead = pHeadA; pHeadA->next = NULL; 之后pHeadA专门利用来组建新list,Old和B这两个list的第一个Node相比,谁小谁接在A的第一个Node处。
对Old和B是摘的动作,对A来说就是一个插入的动作,最终就是最简单动作的集合。
注意利用q,p来明确关系和位置。
qa = pOldHead; pa = qa->next;
qb = pHeadB; pb = qb->next;
qNew = pHeadA; pNew = qNew->next;
while (NULL != pa && NULL != pb)
{
if (pa->data < pb->data)
{
// get node from Old
qa->next = pa->next;
// insert node to New A
Pa->next = pNew;
qNew->next = pa;
// reset the position
Pa = qa->next;
pNew = qNew->next;
}
}
附一个位操作练习,两个要点,
1,a = a&(a-1);
就是每次把最后位的1消去。如下
0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 |
减1后:0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 |
&后:0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
2,16进制向2进制的转换
0x270F
就简单的方向就是1位0x对4位2进制,
F:
1 | 1 | 1 | 1 |
27:
0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 |
结果就是数数,数1的个数。
int function_a ( int n )
{
int a = n;
int count = 0;
while (a)
{
count ++;
a = a&(a-1);
}
return count;
}
void main(int argc, char ** argv)
{
int n = function_a( 0x270F);
printf("%d", n);
}