单链表的就地逆置:
就地逆置即空间复杂度为O(1)
一:用数组存储单链表的值,然后重新逆序赋值,效率较低。
二:利用三个指针,在原来的基础上进行逆序。这种方法比较实用,效率也高。
三:从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾。需要新建一个链表,这种方法和第二种差不多。
解法一:
将头结点摘下,然后从第一结点开始,依次前插入到头结点的后面(头插法建立单链表),直到最后一个结点为止
void reverseList1(LinkList *l) {
LinkList p, temp; //p为工作指针,temp为p的后继,以防断链
p = (*l)->next; //从第一个元素结点开始
(*l)->next = NULL; //将L的next域置为null
while (p) {
temp = p->next; //暂存p的后继
p->next = (*l)->next; //将p结点插入到头结点之后
(*l)->next = p;
p = temp;
}
}
解法二:
假设pre,p和r指向3个相邻的结点,假设经过若干操作,pre之前的结点的指针都已调整完毕,他们的next都指向其原前驱结点。现在令p结点的next域指向pre结点,为防止p的后继结点断开,用r来指向原*p的后继结点。
处理时注意两点:
一,在处理第一个结点时,应将next域置为NULL,应为要作为新表的尾结点
二,处理完最后一个结点,要将头结点的指针指向它。
void reverseList2(LinkList *l) {
LinkList pre, cur, next; //前驱,中间,后继节点
pre = (*l);
cur = pre->next;
while (cur) {
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
//这里翻转完成之后起初的头结点就是尾节点了。
(*l)->next = NULL;
(*l) = pre;
}
单链表的逆序输出:
void R_Print(LinkList L){
if(L->next) {
R_print(L->next);
}
print(L->data);
}
网友评论