链表创建、扩展、输出的详细解释在上篇文章,地址为:c语言-链表的构造与输出接描述
这篇文章详细讲解链表的反转。为了写这个链表反转的代码,绞劲脑汁。方法不一定最好,但是可以满足功能。
反转的思想是:直接进行将前一个结构体变量的地址给下一个结构体变量的指针成员变量。
具体分析过程如下:
C语言代码实现如下:
#include#include #include #include #include using namespace std; //定义结构体并重命名为node typedef struct s_node { int a; s_node *pnext; }node; //创建一个链表 node *creat_list() { node *head = ( node*) malloc(sizeof(node)); //给头指针赋值,这里赋的值应该是node类型的指 //针,所以前面需要node*,因为是类型强制转换,所以考虑到优先级问题,正确写法为(node *) if (head != NULL) { head->a = -1; (*head).pnext = NULL; } return head; }; int add_node(node *new_head,node *new_node ) { //思考new_head++表示什么? for (; new_head->pnext != NULL;new_head= new_head->pnext) { //printf_s("%d", new_head->a); //printf_s("?"); } //printf_s("n"); (*new_head).pnext = new_node; //(*new_node).pnext =NULL; return 0; } node *create_new_node(int node_data) { node *new_node = (node *)malloc(sizeof(node)); if (new_node != NULL) { (*new_node).a = node_data; (*new_node).pnext = NULL; } return new_node; } //反转链表 node *revert_list(node *revert_head) { //定义三个结构体node类型的指针变量,temp用来存放上一个节点的首地 //址,p下一个节点的首地址(当下一个节点不存在时,该节点的地址为null)。 node *p= revert_head->pnext,*temp= revert_head,*ex; //判断是否为空。 while ( p->pnext != NULL) { //将p指针的后一个节点地址给ex指针,即ex指针用于存储第三个节点的地址。 ex = p->pnext; //将前一个节点的地址给后一个节点的指针变量。 p->pnext =temp; //将temp的指针向前移动一个节点的长度 temp = p; //将p指针向后移动一个节点的长度。 p= ex; } //当p位于最后一个节点时,把上一个节点的地址给p的指针变量。 p->pnext = temp; //将p的指针变量赋值为NULL revert_head->pnext = NULL; return p; } void free_list(node *clc) { if (clc == NULL) return; node *p = clc; while (p = (*p).pnext) { clc->pnext = (*p).pnext; free(p); p = clc; } free(clc); } void prin(node *dis_head) { do { //printf_s("*"); printf_s("%d",dis_head->a ); dis_head =(*dis_head).pnext; } while (dis_head!=NULL); } int main() { node *head = creat_list(); //扩展链表 for (int i = 1; i < 8; i++) { add_node(head, create_new_node(i)); //扩展链表需要链表的首地址,这里的参数怎么传递。 //printf_s("%dn",i); } //输出原始链表 printf_s("beforen"); prin(head); //反转链表 head = revert_list(head); //输出链表 printf_s("nresultn"); prin(head); //释放链表空间 free_list(head); return 0; }
运行结果:



