例2:单链表就地逆置问题
逆置就是使得表中内容由原来的
(a1,a2,?ai?1,ai,ai?1,?,an)变成(an,an?1,?ai?1,ai,ai?1,?,a1)
就地逆置就是不需要额外申请结点空间,只需要利用原有的表中的结点空间。
算法思路:借鉴头插入法建链表的方法: 1)记录原表第一个元素结点的地址 2)将头结点的next域置空得新的空链表
3)从原有单链表上依次“摘下”结点,并采用头插法插入到新的新的链表中。 算法:
typedef struct Node {
int data;
struct Node *next; }Node,*LinkList;
void ReverseList(LinkList L) {
Node *p,*q; p=L->next;
L->next=NULL; while(p!=NULL) { q=p->next; p->next=L->next; L->next=p; p=q; } }
例3:二进制数加1运算
建立一个带头结点的线性链表,用以存放输入的二进制数,链表中每个结点的data域存放一个二进制位。并在此链表上实现对二进
制数加1的运算。
问题分析:
① 建链表:二进制数可用带头结点的单链表存储,第一个结点存储二进制数的最高位。
② 二进制数加1运算规则:从低位往高位找到第一个值为0的位,把该位改为1,其后所有各位改为0.
③ 链表实现方法:从高位往低位,从第一个结点开始,找出最后一个值域为0的结点,把该结点值域赋为1,其后所有结点赋为0.
④ 若在链表中未找到值域为0的结点,则表示该二进制数各位均为1,此时,申请一新结点,值域置为1,头插入到原链表,其后所有结点的值域置为0.
算法:
typedef struct Node {
int data;
struct Node *next; }Node,*LinkList;
void BinAdd(LinkList L) {
Node *p,*s,*r; r=L;
p=L->next;
while(p!=NULL)/*寻找最后一个是0的地方*/ { if(p->data==0) r=p; /*r记录最后一个是0的位置*/ p=p->next; }
if(r!=L) r->data=1; else { s=(Node *)malloc(sizeof(Node)); s->data=1; s->next=L->next;
}
L->next=s; r=s; }
r=r->next;
while(r!=NULL) { r->data=0; r=r->next; }