前言
单链表的逆置图解
方式一:非递归
原理
非递归逆置单链表的本质是创建一个新的链表,遍历原先的链表,利用头插法将节点插入新的链表当中去。
图解
实现代码
//链表节点定义
typedef struct link_list{
int data;
struct link_list *next;
}singel_link_t;
/*********************************************************************
* @fn reversion_head_insert
*
* @brief 非递归的方式创建逆置链表
*
* @param link_head为需要逆置的链表表头
*
* @return 返回逆置链表的头节点
*/
singel_link_t *reversion_head_insert(singel_link_t *link_head)
{
singel_link_t *reversion_head=NULL,*node=NULL;
//参数判断
if(link_head==NULL)
{
return NULL;
}
//遍历整个链表
while(link_head!=NULL)
{
node = (singel_link_t *)malloc(sizeof(singel_link_t));
node->data = link_head->data;
if(reversion_head==NULL)//首次添加节点
{
reversion_head = node;
node->next = NULL;
}
else
{
//头插法插入节点
node->next = reversion_head;
reversion_head = node;
}
link_head = link_head->next;
}
return reversion_head;
}
方式二:递归
原理
递归的方式是将链表的范围进行缩小,分为已逆置和未逆置两部分,已逆置部分可以看成一个整体,从未逆置的部分中拿出节点,添加到已逆置的部分中去,直至全部逆置完毕。
图解
将头指针递归到最后一个节点,当头指针在最后一个节点时为递归出口,返回上一层递归
倒数第二层递归,进行逆置
逆置过程
node = head->next;//得到下一个节点
node->next = head;//逆置
head-> = NULL;//置空
返回倒数第三层递归
第二个节点逆置
返回倒数第四层递归
最后一个节点进行逆置
实现代码
//链表节点定义
typedef struct link_list{
int data;
struct link_list *next;
}singel_link_t;
/*********************************************************************
* @fn reversion_recursion
*
* @brief 递归的方式创建逆置链表
*
* @param link_head为需要逆置的链表表头
*
* @return 返回逆置链表的头节点
*/
singel_link_t *reversion_recursion(singel_link_t *link_head)
{
singel_link_t *node,*rlink_head;
if(link_head==NULL||link_head->next==NULL)
{
return link_head;
}
rlink_head = reversion_recursion(link_head->next);
node = link_head->next;//保存下一个节点
node->next = link_head;//下一个节点的next指向当前节点
link_head->next = NULL;
return rlink_head;
}
完整实现
代码
#include <stdio.h>
#include <stdlib.h>
typedef struct link_list{
int data;
struct link_list *next;
}singel_link_t;
/*********************************************************************
* @fn create_link
*
* @brief 创建链表
*
* @param n为链表长度
*
* @return 返回创建链表的头节点
*/
singel_link_t *create_link(int n)
{
int i;
singel_link_t *link_head=NULL,*node=NULL,*tail=NULL;
for(i=0; i<n; ++i)
{
node = (singel_link_t *)malloc(sizeof(singel_link_t));
node->data = i;
if(i==0)//首次添加节点
{
link_head = node;
tail = node;
node->next = NULL;
}
else
{
node->next = tail->next;
tail->next = node;
tail = node;
}
}
return link_head;
}
/*********************************************************************
* @fn reversion_head_insert
*
* @brief 非递归的方式创建逆置链表
*
* @param link_head为需要逆置的链表表头
*
* @return 返回逆置链表的头节点
*/
singel_link_t *reversion_head_insert(singel_link_t *link_head)
{
singel_link_t *reversion_head=NULL,*node=NULL;
if(link_head==NULL)
{
return NULL;
}
while(link_head!=NULL)
{
node = (singel_link_t *)malloc(sizeof(singel_link_t));
node->data = link_head->data;
if(reversion_head==NULL)//首次添加节点
{
reversion_head = node;
node->next = NULL;
}
else
{
node->next = reversion_head;
reversion_head = node;
}
link_head = link_head->next;
}
return reversion_head;
}
/*********************************************************************
* @fn reversion_recursion
*
* @brief 递归的方式创建逆置链表
*
* @param link_head为需要逆置的链表表头
*
* @return 返回逆置链表的头节点
*/
singel_link_t *reversion_recursion(singel_link_t *link_head)
{
singel_link_t *node,*rlink_head;
if(link_head==NULL||link_head->next==NULL)
{
return link_head;
}
rlink_head = reversion_recursion(link_head->next);
node = link_head->next;//保存下一个节点
node->next = link_head;//下一个节点的next指向当前节点
link_head->next = NULL;
return rlink_head;
}
/*********************************************************************
* @fn del_singel_link
*
* @brief 销毁链表
*
* @param link_head为需要销毁的链表表头
*
* @return none
*/
void del_singel_link(singel_link_t *link_head)
{
singel_link_t *node=link_head;
while(link_head!=NULL)
{
node = link_head->next;
free(link_head);
link_head = node;
}
}
/*********************************************************************
* @fn print_single_link
*
* @brief 输出一条链表
*
* @param link_head为需要输出的链表表头
*
* @return none
*/
void print_singel_link(singel_link_t *link_head)
{
while(link_head!=NULL)
{
printf("%d", link_head->data);
if(link_head->next!=NULL)
{
printf("->");
}
else
{
printf("\n");
}
link_head = link_head->next;
}
}
int main()
{
int n;
singel_link_t *link_head=NULL,*rlink_head=NULL;
scanf("%d", &n);
//创建链表
link_head = create_link(n);
print_singel_link(link_head);
//非递归逆置
rlink_head=reversion_head_insert(link_head);
print_singel_link(rlink_head);
//递归逆置
link_head = reversion_recursion(link_head);
print_singel_link(link_head);
//销毁链表
del_singel_link(link_head);
del_singel_link(rlink_head);
return 0;
}