单链表头插法逆序
1.定义节点结构
// 定义节点的数据结构
typedef struct LNode{
int data; // 数据域
struct LNode *next; // 指针域
} Node, *LinkList;
2.链表初始化
// 链表初始化
LinkList InitLinkList(){
LinkList p;
p = (LinkList)malloc(sizeof(Node));
p->data = NULL; // 头结点【指针指向头结点】
p->next = NULL;
return p;
}
3.头插逆序原理
初始链表如下图
想要变成逆序链表如下图
动态展示头插逆序原理
查看原文连接:https://blog.csdn.net/makerjack001/article/details/109295884?ops_request_misc=&request_id=&biz_id=102&utm_term=%E5%8D%95%E9%93%BE%E8%A1%A8%E9%80%86%E7%BD%AE%E2%80%94%E5%A4%B4%E6%8F%92%E6%B3%95%E5%9B%BE%E8%A7%A3&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-5-109295884.142v73pc_new_rank,201v4add_ask,239v2insert_chatgpt&spm=1018.2226.3001.4187
具体操作我这借鉴几张图便于理解,带头结点的需要将头结点断开,后面的节点依次再用头插法插入,不带头结点的构造一个空指针重新插入
4.具体代码
-
带头结点
// 单链表逆置【带头结点】 bool Reverse(LinkList &L){ /* 思路:先将头节点断开,后面的节点逐个断开使用头插法再插入一遍 */ Node q; Node p = L->next; //p节点是逐步后要操作的节点 L->next = NULL; // 头指针指先指向空 while (p != NULL) { q = p; // q是当前要操作的节点 p = p->next; // 下一个要操作的节点 q->next = L->next; // 把要操作的节点从原链表中"断开", 从新插入到头节点后面【所谓头插法】 L->next = q; } return true; }
-
不带头结点
// 链表逆置头插法【不带头结点】 bool Rervse2(LinkList &L){ /* 思路: 原理都和带头结点差不多,不同的是需要定义一个空的头指针 */ if(L == NULL){ // 空表直接返回 return true; } Node *q; // 定义要处理的节点 Node *p = L; //p节点是逐步后要操作的节点【直接从L开始】 LinkList head = NULL; // 定义一个空的指针作为头节点 while (p != NULL) { q = p; // 要被断开的节点 p = p->next; //下一个将要操作的节点 q->next = head; // 节点断开查询插入到L中 head = q; // 头指针移动到q上 }; L = head; return true; }
参考自下面博文
https://blog.csdn.net/makerjack001/article/details/109295884?ops_request_misc=&request_id=&biz_id=102&utm_term=%E5%8D%95%E9%93%BE%E8%A1%A8%E9%80%86%E7%BD%AE%E2%80%94%E5%A4%B4%E6%8F%92%E6%B3%95%E5%9B%BE%E8%A7%A3&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-5-109295884.142^v73^pc_new_rank,201^v4^add_ask,239^v2^insert_chatgpt&spm=1018.2226.3001.4187