#include <stdio.h> #include <malloc.h> #include "jianzhioffer_list.h" #define MAX_LIST_NODE 128 struct list_node *p_arr[MAX_LIST_NODE] = {NULL}; status init_list(struct list_node **head) { int value = 0; struct list_node *p; struct list_node *rear; /* 便于尾部插入新创建的结点 */ int i = 0; (*head) = NULL; printf("please input the value of the inserted node:"); scanf("%d", &value); while (value != -999) { p = (struct list_node*)malloc(sizeof(struct list_node)); p_arr[i++] = p; /* 存放链表指针的全局数组 */ if (!p) { printf("%s: malloc failed\n", __FUNCTION__); return ERROR; } printf("p = 0x%8x\n", (unsigned int)p); p->data = value; if (!*head) { (*head) = p; (*head)->next = NULL; rear = p; } else { rear->next = p; p->next = NULL; rear = p; } printf("please input the value of the inserted node:"); scanf("%d", &value); } return OK; } /* 面试题5:从头到尾打印链表 */ /* 1、注意递归是隐式栈,嵌套过深会导致栈溢出,最好用显式栈 */ void reverse_print_list(struct list_node *head) { if (head) //是if(head),不是while(head) { /* 注释的三句话可以去掉 */ //if (head->next) //{ reverse_print_list(head->next); //} printf("%d ", head->data); } } /* 面试题13:在O(1)时间删除链表结点 */ void delete_list_node(struct list_node **head, struct list_node *deleted) { struct list_node *p; if (!head || deleted) { return; } if (*head == deleted) /* 删除结点为头结点 */ { p = (*head)->next; free(deleted); (*head) = p; } else if (deleted->next) /* 删除结点非头结点,亦非尾结点 */ { p = deleted->next; deleted->data = p->data; deleted->next = p->next; free(p); p = NULL; } else /* 删除节点为非头结点,是尾结点 */ { p = *head; while (p->next != deleted) { p = p->next; } p->next = NULL; free(deleted); deleted = NULL; } } /* 面试题15:求链表中倒数第k个结点 */ struct list_node* get_kth_list_node(struct list_node *head, int k) { struct list_node *front; struct list_node *behind; int i; if (!head || (k <= 0)) { return NULL; } front = behind = head; for (i = 1; i < k; i++) { if (front->next) { front = front->next; } else { return NULL; } } while (front->next) { front = front->next; behind = behind->next; } return behind; } /* 面试题16:反转链表 */ void reverse_list(struct list_node* *head) { struct list_node *p1; struct list_node *p2; struct list_node *p; if (!*head) { return; } p1 = *head; p2 = (*head)->next; while (p2) { p = p2->next; p2->next = p1; p1 = p2; p2 = p; } (*head)->next = NULL; *head = p1; } /* 面试题16:反转链表之递归:首先以第一个为一组,剩余为一组。然后递归地反转剩余,直到一个节点的next为空,* * 另外调用该函数的函数置原链表的第一个节点的next为空,不能在该函数中置NULL。 */ struct list_node* reverse_list_recursive(struct list_node *cur, struct list_node* *head) { struct list_node *tmp; /* 判断cur为空是第一次进入该函数时作判断, 后续只会判断cur->next */ if (!cur || !cur->next) { *head = cur; return cur; } tmp = reverse_list_recursive(cur->next, head); tmp->next = cur; return cur; } /* 面试题17:合并两个递增的链表 */ struct list_node* merge_list(struct list_node *head1, struct list_node *head2) { struct list_node *p1 = head1; struct list_node *p2 = head2; struct list_node *temp; struct list_node *head3; /* temp的next结点指向合并的第一个真正的结点 */ struct list_node *p; if (!head1) { return head2; } else if (!head2) { return head1; } temp = (struct list_node*)malloc(sizeof(struct list_node)); if (!temp) { printf("%s: malloc failed\n", __FUNCTION__); return NULL; } p = temp; p->next = NULL; while (p1 && p2) { if (p1->data <= p2->data) { p->next = p1; p = p->next; p1 = p1->next; } else { p->next = p2; p = p->next; p2 = p2->next; } } /* if (!p1) { while (p2) { p->next = p2; p = p->next; p2 = p2->next; } } if (!p2) { while (p1) { p->next = p1; p = p->next; p1 = p1->next; } } */ p->next = p1 ? p1: p2; head3 = temp->next; free(temp); return head3; } int get_list_len(struct list_node *head) { int count = 0; while (head) { count++; head = head->next; } return count; } /* 面试题26:复杂链表的复制 */ #if 1 /* 该题只写出代码,不调试 */ struct list_node_complex { l_elemtype data; struct list_node_complex *next; struct list_node_complex *sibling; }; void clone_node(struct list_node_complex *head) { struct list_node_complex *cur = head; struct list_node_complex *clone; while (cur) { clone = (struct list_node_complex *)malloc(sizeof(struct list_node_complex)); if (!clone) { printf("%s: malloc failed\n", __FUNCTION__); return; } clone->data = cur->data; clone->sibling = NULL; clone->next = cur->next; cur->next = clone; cur = cur->next; } } void clone_sibling(struct list_node_complex *head) { struct list_node_complex *cur = head; struct list_node_complex *clone; while (cur) { clone = cur->next; if (clone->sibling) { clone->sibling = clone->sibling->next; } cur = clone->next; } } struct list_node_complex *separate(struct list_node_complex *head) { struct list_node_complex *cur = head; struct list_node_complex *clone; struct list_node_complex *clone_head; if (cur) { clone = cur->next; clone_head = clone; cur->next = clone->next; cur = cur->next; } while (cur) { clone->next = cur->next; clone = clone->next; cur->next = clone->next; cur = cur->next; } return clone_head; } struct list_node_complex *clone(struct list_node_complex *head) { clone_node(head); clone_sibling(head); return separate(head); } #endif /* 面试题37:两个链表的第一个公共节点 */ struct list_node * get_first_common_node(struct list_node *head1, struct list_node *head2) { int len1 = 0; int len2 = 0; int diff_len; struct list_node *p1; struct list_node *p2; int i; if (!head1 || !head2) { return NULL; } len1 = get_list_len(head1); len2 = get_list_len(head2); diff_len = len1 - len2; p1 = head1; p2 = head2; if (diff_len < 0) { p1 = head2; p2 = head1; diff_len = len2 - len1; } for (i = 1; i <= diff_len; i++) { p1 = p1->next; } while (p1 && p2) { if (p1 == p2) { return p1; } else { p1 = p1->next; p2 = p2->next; } } return NULL; } void print_list(struct list_node *head) { while (head) { printf("addr(0x%8x) -> value(%d)\n", (unsigned int)head, (unsigned int)head->data); head = head->next; } } int main(void) { struct list_node *head; struct list_node *head1; struct list_node *head2; struct list_node *merge_head; struct list_node *common_node; struct list_node *p; int i; int k; init_list(&head); print_list(head); struct list_node *first_node = reverse_list_recursive(head, &head); if (first_node) { first_node->next = NULL; } printf("\nreverse the list recursively\n"); print_list(head); #if 0 printf("\nreverse output the list\n"); reverse_print_list(head); printf("\ninput the deleted node's no:"); scanf("%d", &i); delete_list_node(&head, p_arr[i]); print_list(head); printf("\nreverse output the list\n"); reverse_print_list(head); printf("\nplease input the reverse k value:"); scanf("%d", &k); p = get_kth_list_node(head, k); if (p) { printf("output the reverse kth's addr:0x%8x, value:%d\n", p, p->data); } printf("\nreverse the list\n"); reverse_list(&head); print_list(head); #endif #if 0 printf("\n======= init head1 =======\n"); init_list(&head1); printf("\n======= print head1 =======\n"); print_list(head1); printf("\n======= init head2 =======\n"); init_list(&head2); printf("\n======= print head2 =======\n"); print_list(head2); printf("\n======= merge head1 && head2 =======\n"); merge_head = merge_list(head1, head2); print_list(merge_head); printf("\n======= print head1 after merge =======\n"); print_list(head1); printf("\n======= print head2 after merge =======\n"); print_list(head2); printf("\n======= head1 && head2 first common node =======\n"); common_node = get_first_common_node(head1, head2); if (common_node) { printf("common_node = 0x%8x, data = %d\n", common_node, common_node->data); } #endif return 0; }