单链表的就地逆置指辅助空间的逆置方法。有普通循环和递归两种方法。

1、普通循环法:普通循环法是逆置链表初始为空,表中节点从原链表中依次“删除”,再逐个插入逆置链表的表头,即“头插”到逆置链表中,使它成为逆置链表的“新”的第一个结点,如此循环,直至原链表为空。

2、递归:递归是先假定有一个函数,可以将以head为头结点的单链表逆序,并返回新的头结点。将链表分为当前表头结点和其余部分,递归的过程就是,先将表头结点从链表中拆出来,然后对其余部分进行逆序,最后将当前的表头结点链接到逆

什么叫“单链表就地逆置”?

比如说链表
a -> b -> c -> d
表头是a,表尾是d。就地逆置的意思就是变成:
a <- b <- c <- d
a变成表尾,d变成表头
假设
struct LINK {
int value;
struct LINK * next;
};
struct LINK a, b, c, d;
a->next = &b;
b->next = &c;
c->next = &d;
d->next = 0;
逆置后:
b->next = &a;
c->next = &b;
d->next = &c;
a->next = 0;
所谓就地逆置,就是在操作中,遇到a->next = &b;的情况,那么改写为b->next = &a;

单链表就地逆置的两种方法(递归与普通循环)

一、用递归算法

对于不带头结点的单链表(a1,a2,a3,a4,a5,a6)逆置后的结果为(a6,a5,a4,a3,a2,a1)

考虑递归算法,若只有一个结点,则直接返回,若存在两个结点(a1,a2)则需要做的操作有:

 a2->next=a1;a1->next=NULL;return a2;

a2即新的头结点,若有三个结点,则应先将子链(a2,a3)先逆置且返回该子链的新的头结点,然后把子链(a2,a3)当作一个复合结点a2',组成新的二元组(a1,a2')然后就可以执行前面相同的操作:a2'->next=a1;a1->next=NULL;return a3'; 即可,多个以上的结点可同理得到,

Node *Reverse(Node *head)

{

 Node *p=head;

 if(p==NULL)

  return NULL; //若是空链表,返回空

 Node *q=p->next;

 if(q==NULL)

  return p; //若只有一个结点,直接返回

 else

 head=Reverse(q);//记录子序列的新的头结点

 q->next=p; //当前结点与已经逆置的子序列看成是前后的两个结点p,q,作相应的逆置操作

 p->next=NULL;

 return head;    //返回新的子序列的头结点

}

二、用普通算法循环逆置(头插法重新建立带头结点的新链表)

参考链接:https://blog.csdn.net/onlyoncelove/article/details/81988514

单链表的就地逆置的算法!!

就地逆置即算法的辅助空间为O(1)。

思路为:逆置链表初始为空,表中节点从原链表中依次“删除”,再逐个插入逆置链表的表头(即“头插”到逆置链表中),使它成为逆置链表的“新”的第一个结点,如此循环,直至原链表为空。

实现代码:

void converse(LinkList *head)  
{  
    LinkList *p,*q;  
    p=head->next;  
    head->next=NULL;  
    while(p)  
    {  
        /*向后挪动一个位置*/  
        q=p;  
        p=p->next;  
          
        /*头插*/  
        q->next=head->next;  
        head->next=q;  
    }  
}

链表就地逆置p->next=head->next意思

注意head每次指向哪个节点
head->next总是指向已经经过逆置的最后一个节点,也就是新的经过逆置的头节点
所以每次完成一个新的节点的逆置,要将其next指向上一个逆置的节点,刚好是head->next指向的节点
比如原来有链表 A->B->C->D->NULL
开始head->next = A, head->next->next=B
首先让p=A,并让A->next=NULL, 也就是让A成为尾节点
然后q指向B,此时head->next还是指向A的,也就是刚刚完成逆置的节点
while开始之后
每次都将q赋值给p,于是 p=B, q =C, B->next=head->next = A, head-next = B
此时head->next指向B,刚好又是刚完成逆置的节点
以后继续循环

试写一算法对单链表实现就地逆置?

void Inverse(LinkList &L)
{
 LNode *p, *q;
p = L->next;             /*记录第一个结点地址*/
L->next = NULL;      /*把链表设置成空表*/
while (p != NULL)    /*依次按头插法将各结点插入,就实现了逆置*/
{
q = p;                              /*用q记录待插入结点地址*/
p = p->next;                    /*用p记录待插入结点的后继结点地址*/*/
q->next = L->next;          /*将q(待插入结点)插入到头结点的前面*/
L->next = q;                    /*将新插入结点作为新的头*/
}

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

对单链表实行就地逆置算法?

其实就是建立链表有的头插法
#define ElemType char
typedef struct Node{
    ElemType data;
    struct Node *next;
}Node,*LinkList;
void ReverseList(LinkList L)
{
    Node *p,*q;
    p = L->next;             /*p为原链表的当前处理节点*/
    L->next = NULL;          /*逆置单链表初始为空*/
    
    while(p != NULL){        /*当原链表未处理完*/
        q = p->next;         /*q指针保留原链表当前处理节点的下一个节点*/
        p->next = L->next;   /*将当前处理节点p插入到逆置L的表头*/
        L->next = p;
        p = q;               /*p指向下一个待插入的节点*/
    }
}

单链表逆置问题!不是就地逆置是将逆置的结果存放于另一单链表中 但是原单链表不变!

struct N
{
T data; // 这个的类型根据需要改
N *next;
};
N* revert(N* l)
{
N *ret = NULL;
while (l != NULL)
{
N *newnode = new N;
newnode->data = l->data;
newnode->next = ret;
ret = newnode;
l = l->next;
}
return ret;
}

关于单链表的所有结点逆置

//就地逆置单链表
//定义结点数据元素结构体
typedef struct snode
{
DataType x;
struct snode *next;
}SLNode;
//逆置算法
void ListReverse(SLNode *head)
{
int i=-1,j;
DataType x;
SLNode *p,*q;
p=head;
while(p->next!=NULL&&i<(ListLength(head)-1)/2)
{
p=p->next;
i++;
q=head;
j=-1;
while(q->next!=NULL&&j<ListLength(head)-1-i)
{
q=q->next;
j++;
}
x=p->data;
p->data=q->data;
q->data=x;
}
}

已知带头结点的单链表L,编写算法删除L中国从k开始的n个元素,并将得到的链表就地逆置

bool Del_k_n(LinkList &linkList,int k,int n){
LNode *pre=linkList->next,*r,*p=linkList;
while (pre!=NULL&&(--k)!=0){//查找开始结点
p=pre;
pre=pre->next;
}
if (pre==NULL) return false;//开始结点为空,删除失败
r=pre;
while (r!=NULL&&(--n)!=0){//查找结束结点
r=r->next;
}
p->next=r->next;
while (pre!=p->next){//删除元素
r=p->next;
free(pre);
pre=r;
}
p=linkList->next;
linkList->next=NULL;
while (p){//逆置
r=p->next;
p->next=linkList->next;
linkList->next=p;
p=r;
}
return true;
}

试分别用顺序表和单链表作为存储结构,实现将线性表(a0,a1,...an-1)就地逆置的操作,所谓"就地"指辅助

——while(q)是指q指的内容不为空的情况下吗?
没错。
——可是之前的语句已经使它为空了呀??
这个不对。
之前对q的赋值就只有这句:q=p->next
并没有把NULL赋值给他
如果你觉得这两句语句q=p->next;
p
->
next=NULL;
具有传递性,于是就等价于q
=
NULL
的话,你需要对指针这个东西有更深入的理解
q=p->next;
是让q只想p的next指针所指的东西,比如q->next本来指向我这个人,那么现在q也指向我了。q->next也指向我,不变。
p
->
next=NULL;
的意思是让p->next
指向空。但是这不影响刚才执行以后
q指向我这个事实