C语言 单链表的反转
一、简述
记--简单的将单链表的数据顺序进行反转。如将原来的顺序1 2 3 4 5 6 7 反转为:7 6 5 4 3 2 1
二、方式1:头插法
2.1 头插法1--类似新建链表
2.1.1 思路:断开链表头,然后以头插法的方式将原链表的数据添加链表。
2.1.2 测试代码
#include <stdio.h>
#include <stdlib.h>
//链表节点定义
typedef struct s_node
{
int data;
struct s_node* pNext;
}Node;
Node* create_list_head();
Node* create_new_node(int node_data);
int add_node_head(Node* head, Node* new_node);
void display_list(Node* head);
void free_list(Node* head);
Node* revert_list(Node* head);
int main(int argc, char *argv[])
{
//创建链表
Node* head = create_list_head();
if(NULL == head)
{
printf("create_list_head failed!\n");
return -1;
}
//填充数据(添加节点)
int i;
for(i=1; i<8; i++)
add_node_head(head, create_new_node(i));
//打印原来链表数据
printf("befor ");
display_list(head);
//反转链表
head = revert_list(head);
printf("after ");
display_list(head);
//释放链表空间
free_list(head);
return 0;
}
//创建链表
Node* create_list_head()
{
Node* head = (Node*)malloc(sizeof(Node));
if(NULL != head)
{
head->data= -1;
head->pNext= NULL;
}
return head;
}
//创建新节点
Node* create_new_node(int node_data)
{
Node* new_node = (Node*)malloc(sizeof(Node));
if(NULL != new_node)
{
new_node->data= node_data;
new_node->pNext= NULL;
}
return new_node;
}
//头插法
int add_node_head(Node* head, Node* new_node)
{
if(NULL == head || NULL == new_node)
return -1;
new_node->pNext = head->pNext;
head->pNext = new_node;
return 0;
}
//打印链表数据
void display_list(Node* head)
{
if(NULL == head)
return;
Node* tmp = head;
printf("list data:");
while(NULL !=(tmp=tmp->pNext))
{
printf("%d ", tmp->data);
}
printf("\n");
}
//释放链表
void free_list(Node* head)
{
if(NULL == head)
return;
Node* p = head;
while(p = p->pNext)
{
head->pNext = p->pNext;
//printf("free:%d\n", p->data);
free(p);
p = head;
}
free(head);
}
//头插方式1-反转链表
Node* revert_list(Node* head)
{
if(NULL == head)
return;
Node* p = head->pNext;
head->pNext= NULL;
Node* tmp = NULL;
while(p)
{
tmp = p->pNext;
add_node_head(head, p);
p = tmp;
}
return head;
}
2.1.3 测试结果
2.2 头插法2 --与方式1雷同
2.2.1 思路:除了第一个逐个往插入到最前面
2.2.2 测试代码
#include <stdio.h>
#include <stdlib.h>
//链表节点定义
typedef struct s_node
{
int data;
struct s_node* pNext;
}Node;
Node* create_list_head();
Node* create_new_node(int node_data);
int add_node_head(Node* head, Node* new_node);
void display_list(Node* head);
void free_list(Node* head);
Node* revert_list(Node* head);
int main(int argc, char *argv[])
{
//创建链表
Node* head = create_list_head();
if(NULL == head)
{
printf("create_list_head failed!\n");
return -1;
}
//填充数据(添加节点)
int i;
for(i=1; i<8; i++)
add_node_head(head, create_new_node(i));
//打印原来链表数据
printf("befor ");
display_list(head);
//反转链表
head = revert_list(head);
printf("after ");
display_list(head);
//释放链表空间
free_list(head);
return 0;
}
//创建链表
Node* create_list_head()
{
Node* head = (Node*)malloc(sizeof(Node));
if(NULL != head)
{
head->data= -1;
head->pNext= NULL;
}
return head;
}
//创建新节点
Node* create_new_node(int node_data)
{
Node* new_node = (Node*)malloc(sizeof(Node));
if(NULL != new_node)
{
new_node->data= node_data;
new_node->pNext= NULL;
}
return new_node;
}
//头插法
int add_node_head(Node* head, Node* new_node)
{
if(NULL == head || NULL == new_node)
return -1;
new_node->pNext = head->pNext;
head->pNext = new_node;
return 0;
}
//打印链表数据
void display_list(Node* head)
{
if(NULL == head)
return;
Node* tmp = head;
printf("list data:");
while(NULL !=(tmp=tmp->pNext))
{
printf("%d ", tmp->data);
}
printf("\n");
}
//释放链表
void free_list(Node* head)
{
if(NULL == head)
return;
Node* p = head;
while(p = p->pNext)
{
head->pNext = p->pNext;
//printf("free:%d\n", p->data);
free(p);
p = head;
}
free(head);
}
//新建链表方式-反转链表
Node* revert_list(Node* head)
{
if(NULL == head)
return;
Node* p = head->pNext;
Node* q = NULL;
while(q = p->pNext)
{
p->pNext = q->pNext;//分离q
add_node_head(head, q);//将q插入到首元素位置
}
return head;
}
2.2.3 测试结果
三、方式2 尾插方式
3.1 思路:找到最后一个元素,然后从第一个元素逐个插入到尾部。
3.2 测试代码
#include <stdio.h>
#include <stdlib.h>
//链表节点定义
typedef struct s_node
{
int data;
struct s_node* pNext;
}Node;
Node* create_list_head();
Node* create_new_node(int node_data);
int add_node_tail(Node* head, Node* new_node);
void display_list(Node* head);
void free_list(Node* head);
Node* revert_list(Node* head);
int main(int argc, char *argv[])
{
//创建链表
Node* head = create_list_head();
if(NULL == head)
{
printf("create_list_head failed!\n");
return -1;
}
//填充数据(添加节点)
int i;
for(i=1; i<8; i++)
add_node_tail(head, create_new_node(i));
//打印原来链表数据
printf("befor ");
display_list(head);
//反转链表
head = revert_list(head);
printf("after ");
display_list(head);
//释放链表空间
free_list(head);
return 0;
}
//创建链表
Node* create_list_head()
{
Node* head = (Node*)malloc(sizeof(Node));
if(NULL != head)
{
head->data= -1;
head->pNext= NULL;
}
return head;
}
//创建新节点
Node* create_new_node(int node_data)
{
Node* new_node = (Node*)malloc(sizeof(Node));
if(NULL != new_node)
{
new_node->data= node_data;
new_node->pNext= NULL;
}
return new_node;
}
//尾插法
int add_node_tail(Node* head, Node* new_node)
{
if(NULL == head || NULL == new_node)
return -1;
Node* tmp = head;
while( NULL != tmp->pNext )//遍历链表到尾部
{
tmp = tmp->pNext;
}
tmp->pNext = new_node;
new_node->pNext = NULL;
return 0;
}
//打印链表数据
void display_list(Node* head)
{
if(NULL == head)
return;
Node* tmp = head;
printf("list data:");
while(NULL !=(tmp=tmp->pNext))
{
printf("%d ", tmp->data);
}
printf("\n");
}
//释放链表
void free_list(Node* head)
{
if(NULL == head)
return;
Node* p = head;
while(p = p->pNext)
{
head->pNext = p->pNext;
//printf("free:%d\n", p->data);
free(p);
p = head;
}
free(head);
}
//尾插方式-反转链表
Node* revert_list(Node* head)
{
if(NULL == head)
return;
Node* p = head->pNext, *q, *end = head;
while( NULL != end->pNext )//使得end指向链表最后一个元素
{
end = end->pNext;
}
q = end;
while(p != end)
{
head->pNext= p->pNext;//分离p
add_node_tail(head, p);//将p插入到末尾位置
p = head->pNext;//p指向第一个元素
}
return head;
}
3.3 测试结果