大家都知道单链表是只能前结点找到后结点的,关于单链表的逆置也困扰了我很久,终于受不了了,进行了一番重新学习
在我学到的方法有这么几种:三指针法(也可以理解为辅助指针法)、头插法、今天学到的递归;
壹、三指针法:我们先来看这个理解图
这个图看上去应该可以很好的理解这种方法;
下面就是三指针法的实现:
typedef int DataType; //类型定义
typedef struct node{ //单链表定义
DataType data;
struct node* next;
}LinkedNode,*LinkList;
void ReverseList(LinkList& ListHead)
{
cout<<"Begin to Reverse the List"<<endl;
if( (NULL==ListHead)||(NULL==ListHead->next) )return ; //边界检测
LinkedNode* pPre=ListHead; //先前指针
LinkedNode* pCur=pPre->next; //当前指针
LinkedNode* pNext=NULL; //后继指针
while(pCur!=NULL)
{
pNext=pCur->next;
pCur->next=pPre;
pPre=pCur;
pCur=pNext;
}
ListHead->next=NULL;
ListHead=pPre; //记录下新的头结点
}
贰、下来就是头插法,这个要稍微理解一下了:是来看理解图
这么看应该就好理解一点了吧 ,就是将L结点指向B ,B结指向A,这样就可以达到逆置,之后我们来看代码
LNode *Inverse(LNode *L)
{
LNode *p, *q;
p = L->next;
L->next = NULL;
while (p != NULL)
{
q = p;
p = p->next;
q->next = L->next;
L->next = q;
}
return L;
}
当然你也可以重新重建一个链表,用位结点指向然后将它delete掉这样来达到逆置
就类似于这样来实现
叁、最后一种就是使用递归的方法,还是那个思路,我们先来看图
当然这个实现我学到了两种方法
我们来一一看一下;
第一种是返回值为空的办法
void ReverseList(LinkedNode* pCur,LinkList& ListHead)
{
if( (NULL==pCur)||(NULL==pCur->next) )
{
ListHead=pCur;
}
else
{
LinkedNode* pNext=pCur->next;
ReverseList(pNext,ListHead); //递归逆置后继结点
pNext->next=pCur; //将后继结点指向当前结点。
pCur->next=NULL;
}
}
第二种是返回结点l类型
LinkedNode* ReverseList(LinkedNode* pCur,LinkList& ListHead)
{
cout<<"Begin to Reverse the List"<<endl;
if( (NULL==pCur)||(NULL==pCur->next) )
{
ListHead=pCur;
return pCur;
}
else
{
LinkedNode* pTemp=ReverseList(pCur->next,ListHead); //递归逆置后继结点
pTemp->next=pCur; //将后继结点指向当前结点
pCur->next=NULL;
return pCur;
}
}
z这些方法你都可以去尝试,当然三指针法和头插法应该好理解一点。