无头结点单链表的逆置_第1章第2节练习题11 就地逆置单链表
## 問(wèn)題描述
> 試編寫(xiě)在帶頭結(jié)點(diǎn)的單鏈表就地逆置,所謂“就地”是指輔助空間為O(1)
## 算法思想1
> 將頭結(jié)點(diǎn)摘下,然后從第一個(gè)結(jié)點(diǎn)開(kāi)始,依次插入到頭節(jié)點(diǎn)的后面(類(lèi)似與頭插法創(chuàng)建單鏈表),直到最后一個(gè)結(jié)點(diǎn)為止,實(shí)現(xiàn)了鏈表的逆置。如下圖所示:

## 算法描述1
~~~
void RverList(LNode *head){
LNode *p=head->next;
LNode *q=p->next;
head->next=NULL;
while(p){
q=p->next;
p->next=head->next;
head->next=p;
p=q;
}
}
~~~
具體代碼見(jiàn)附件1。
## 算法思想2
> 引用三個(gè)指針,分別為指向當(dāng)前結(jié)點(diǎn)的指針p,指向前驅(qū)結(jié)點(diǎn)的指針pre,指向后繼結(jié)點(diǎn)的指針q。首先單獨(dú)摘下頭節(jié)點(diǎn),然后讓指針p所指結(jié)點(diǎn)的next域指向前驅(qū)結(jié)點(diǎn)即可完成一次逆置過(guò)程;但是因?yàn)樾枰嬷谜麠l單鏈表,因此將這三個(gè)指針?lè)謩e后移,繼續(xù)重復(fù)上一次的過(guò)程,具體如下圖所示:

## 算法描述2
~~~
void RverList(LNode *head){
LNode *pre=head;
LNode *p=pre->next;
LNode *q=p->next;
p->next=NULL;
while(q){
pre=p;
p=q;
q=q->next;
p->next=pre;
}
head->next=p;
}
~~~
具體代碼見(jiàn)附件2。
## 附件1
~~~
#include
#include
typedef int ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
LinkList CreatList(LNode*);
void RverList(LNode*);
void Print(LNode*);
int main(int argc, char* argv[])
{
LNode *head;
head=(LNode*)malloc(sizeof(LNode));
head->next=NULL;
head=CreatList(head);
Print(head);
RverList(head);
Print(head);
return 0;
}
//頭插法建立單鏈表
LinkList CreatList(LNode *head)
{
LNode *L;
ElemType x;
scanf("%d",&x);
while(x!=999){
L=(LNode*)malloc(sizeof(LNode));
L->data=x;
L->next=head->next;
head->next=L;
scanf("%d",&x);
}
return head;
}
//就地逆置單鏈表
void RverList(LNode *head){
LNode *p=head->next;
LNode *q=p->next;
head->next=NULL;
while(p){
q=p->next;
p->next=head->next;
head->next=p;
p=q;
}
}
//打印全部結(jié)點(diǎn)
void Print(LNode *head)
{
LNode *p=head->next;
while(p){
printf("%4d",p->data);
p=p->next;
}
printf("\n");
}
~~~
## 附件2
~~~
#include
#include
typedef int ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
LinkList CreatList(LNode*);
void RverList(LNode*);
void Print(LNode*);
int main(int argc, char* argv[])
{
LNode *head;
head=(LNode*)malloc(sizeof(LNode));
head->next=NULL;
head=CreatList(head);
Print(head);
RverList(head);
Print(head);
return 0;
}
//頭插法創(chuàng)建單鏈表
LinkList CreatList(LNode *head)
{
LNode *L;
ElemType x;
scanf("%d",&x);
while(x!=999){
L=(LNode*)malloc(sizeof(LNode));
L->data=x;
L->next=head->next;
head->next=L;
scanf("%d",&x);
}
return head;
}
//就地逆置單鏈表
void RverList(LNode *head){
LNode *pre=head;
LNode *p=pre->next;
LNode *q=p->next;
p->next=NULL;
while(q){
pre=p;
p=q;
q=q->next;
p->next=pre;
}
head->next=p;
}
//打印全部結(jié)點(diǎn)
void Print(LNode *head)
{
LNode *p=head->next;
while(p){
printf("%4d",p->data);
p=p->next;
}
printf("\n");
}
~~~
總結(jié)
以上是生活随笔為你收集整理的无头结点单链表的逆置_第1章第2节练习题11 就地逆置单链表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 数据库下午怎么插入_2020/3/25
- 下一篇: java获取当前分钟_分别获取当前年月日