单链表反转
面试比较频繁且基础的题目,以下是本人用两种不同方法造的轮子。
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 struct node { 5 struct node *next; 6 int val; 7 }; 8 9 #define SIZE 10 10 11 /** 12 * 反转链表 13 * @param head 头指针 14 * @return 返回反转后的头指针 15 */ 16 struct node *reverse_list1(struct node *head) 17 { 18 struct node *prev_node = NULL; 19 struct node *node = head; 20 struct node *temp; 21 while (node != NULL) { 22 temp = node; 23 node = node->next; 24 temp->next = prev_node; 25 prev_node = temp; 26 } 27 return prev_node; 28 } 29 30 /** 31 * 反转列表 32 * @param node 结点指针 33 * @param prev_node 结点前指针 34 * @return 返回反转后的头指针 35 */ 36 struct node *reverse_list2(struct node *node, struct node *prev_node) 37 { 38 struct node *list; 39 if (node == NULL) 40 return prev_node; 41 list = reverse_list2(node->next, node); 42 node->next = (node == prev_node) ? NULL : prev_node; 43 return list; 44 45 } 46 47 48 int main(int argc, char const **argv) 49 { 50 struct node *list; 51 struct node *node, *next_node; 52 int i; 53 list = (struct node *)malloc(sizeof(struct node)); 54 list->val = 0; 55 list->next = NULL; 56 node = list; 57 for (i = 1; i < SIZE; i++) { 58 next_node = (struct node *)malloc(sizeof(struct node)); 59 next_node->next = node->next; 60 node->next = next_node; 61 node = next_node; 62 node->val = i; 63 } 64 for (node = list; node != NULL; node = node->next) 65 printf("%5d", node->val ); 66 printf("\n"); 67 68 list = reverse_list1(list); 69 for (node = list; node != NULL; node = node->next) 70 printf("%5d", node->val ); 71 printf("\n"); 72 list = reverse_list2(list, list); 73 for (node = list; node != NULL; node = node->next) 74 printf("%5d", node->val ); 75 printf("\n"); 76 return 0; 77 }
reverse_list1是通过每个节点的next指针反向指向prev,reverse_list2是利用递归,直接到链表末段再重新把next指向prev。用reverse_list2消耗更多栈。
程序初始化可能比较晦涩,没有写插入节点直接对链表初始化。