题目:利用递归倒置一个链表
此题非常常见,因为很多公司在出面试题的时候,会考察面试人员的数据结构知识和算法知识,而有关链表的题是最具代表性的了。
这种题目不是非常难,适合做面试题,但又不简单,如果不提前做好准备,真正到了面试时,很难能做出来
#include<stdio.h> #include<malloc.h> #include<stdlib.h> #include<assert.h> struct node { int data; struct node* next; }; // build the list {1,2,3,4} in the heap and store its head pointer in a local // stack variable. // Returns the head pointer to the caller struct node* BuildOneTwoThreeFour(); // there is a short and efficient recursive solution to this problem. void RecursiveReverse(struct node** headRef); // print the element in the linked list in order void PrintLinkedList(struct node* head); struct node* BuildOneTwoThreeFour() { struct node* head = NULL; struct node* second = NULL; struct node* third = NULL; struct node* forth = NULL; head = malloc(sizeof(struct node)); second = malloc(sizeof(struct node)); third = malloc(sizeof(struct node)); forth = malloc(sizeof(struct node)); head->data = 1; head->next = second; second->data = 2; second->next = third; third->data = 3; third->next = forth; forth->data = 4; forth->next = NULL; return head; } void RecursiveReverse(struct node** headRef) { struct node* first; struct node* rest; if(*headRef == NULL) return; first = *headRef; rest = first->next; if(rest == NULL) return; RecursiveReverse(&rest); first->next->next = first; first->next = NULL; *headRef = rest; } void PrintLinkedList(struct node* head) { while(head != NULL) { printf("%d ",head->data); head = head->next; } printf("\n"); } int main() { struct node* head = BuildOneTwoThreeFour(); PrintLinkedList(head); RecursiveReverse(&head); PrintLinkedList(head); }
上面这个程序实现了链表的倒置,那个RecursiveReverse函数的内部指针变化,需要花时间去理解。先前,我一直不理解,有一次上课,不想听老师讲课,就把这个程序拿出来看了又看,用了2个小时时间,最后用gdb跟踪调试才搞明白指针的指向,这个方法非常的巧妙,一旦分析出来,就彻底记住了。
所以,一定要花时间分析这个程序,不然很容易就会忘了它的递归思路。
关于链表其实有非常多的面试题,这个倒置链表只是其中非常常见的例子,我近期会更新一些关于链表的文章,主要参考了stanford cs library的资料,对链表做出详尽的分析。