#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> /*一般来说写题目不要因为一个题目编写过多的函数(》=2)。写这么多面试官会觉得你很蠢……,除非是大编程题*/ struct Node{ int data; Node* next; }; Node* CreateList(int val[],int n) { Node* head = (Node*)malloc(sizeof(Node)); head->next = NULL; Node* p = head; for (int i = 0; i < n;i++) { Node* new_node = (Node*)malloc(sizeof(Node)); new_node->data = val[i]; new_node->next = NULL; p->next = new_node; p = new_node; } return head; } Node* CreateCirList(int val[], int n, int start) { Node* head = (Node*)malloc(sizeof(Node)); head->next = NULL; Node* p = head; Node* p_in; for (int i = 0; i < n; i++) { Node* new_node = (Node*)malloc(sizeof(Node)); new_node->data = val[i]; new_node->next = NULL; if (start == i) { p_in = new_node; } p->next = new_node; p = new_node; } p->next = p_in; return head; } /*1. 求单链表中结点的个数*/ int NodeNum(Node* head) { int i = 0; Node* p = head; if (p == NULL) { return 0; } while (p->next != NULL) { i++; p = p->next; } return i; } /*2. 将单链表反转*/ Node* Reverse(Node* head) { if (head == NULL || head->next == NULL) { return head;//Empty } Node* pre, *cur=head->next, *nxt; pre = nxt = NULL; while (cur)//每次循环:调整前面两个指针指向。另外把三个指针都依次向后移动一位。 { nxt = cur->next; cur->next = pre; pre = cur; cur = nxt; } head->next = pre; return head; } /*MTK程序填空题*/ Node* Reverse_MTK(Node* head) { if (head == NULL || head->next == NULL) { return head;//Empty } Node* pre=head, *cur = pre->next, *nxt=cur->next; /*blank*/ pre->next = NULL; while (nxt != NULL) { cur->next = pre; pre = cur; cur = nxt; /*blank*/ nxt = cur->next; } /*blank*/ cur->next = pre; head->next = cur;//MTK原题为head=cur。我修改为这个是因为head-》next=cur是针对有头的链表。 return head; } /*3. 查找单链表中的倒数第K个结点(k > 0)*/ //可以知道总节点个数然后遍历。也可以用两个相隔一定距离的指针 Node* GetBackNode(Node* head,int k) { Node* first = head; Node* second = head; while (k--) { if (second==NULL) { printf("No such Node! "); return head; } second = second->next; } /*此时first和second保持k距离*/ while (second != NULL) { first = first->next; second = second->next; } return first; } /*4. 查找单链表的中间结点*/ /*两个办法,一个知道数量就不说了。另一个两个指针,一个走两个一个走一个,两个的走到头,一个的就是中间位置*/ Node* GetMidNode(Node* head) { Node* first = head, *second = head; if (head == NULL || head->next == NULL || head->next->next == NULL) { return head; } while (first != NULL) { second = second->next; first = first->next; if (first != NULL) { first = first->next; } else { return second; } } return second; } /*5. 从尾到头打印单链表*/ /*用栈,我想到了但是然并卵没什么用。先写进数组,不过这样用链表干嘛呢?看了别人想法,递归是很好的选择*/ void BackPrint(Node* t) {//注意下:输入为head,第一个元素是head-》next。 if (t->next == NULL) { return;//只返回一次 } else { BackPrint(t->next); printf("%d ", t->next->data);//最后一个输出肯定是head-》next的值 } } /*6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序*/ Node* MergeSortedList(Node* pHead1, Node* pHead2) { if (pHead1 == NULL || pHead1->next == NULL) { return pHead2; } if (pHead2 == NULL || pHead2->next == NULL) { return pHead1; } Node* p1 = pHead1->next, *p2 = pHead2->next; Node* new_head = (Node*)malloc(sizeof(Node));new_head->next = NULL; Node* tmp = new_head; if (p1->data <= p2->data) { tmp->next = p1; p1 = p1->next; } else { tmp->next = p2; p2 = p2->next; } tmp = tmp->next; while (p1!=NULL && p2!=NULL) { if (p1->data <= p2->data) { tmp->next = p1; p1 = p1->next; } else { tmp->next = p2; p2 = p2->next; } tmp = tmp->next; } if (p1 != NULL) { tmp->next = p1; } if (p2 != NULL) { tmp->next = p2; } return new_head; } /*7. 判断一个单链表中是否有环*/ int HaveCircle(Node* head) { Node* fast = head, *slow = head; while (fast != NULL && slow != NULL) { fast = fast->next; if (fast != NULL) { fast = fast->next; } else { printf("The List has no circle! "); return 0; } slow = slow->next; if (slow == fast) { printf("The List has at least a circle! "); return 1; } } return 0; } /*8. 判断两个单链表是否相交*/ int IsCross(Node* head1, Node* head2) { Node* p1 = head1, *p2 = head2; while (p1->next != NULL) { p1 = p1->next; } while (p2->next != NULL) { p2 = p2->next; } if (p1 == p2) { return 1; } else { return 0; } } /*9. 求两个单链表相交的第一个节点*/ Node* GetFirstNode(Node* head1, Node* head2) { Node* p1 = head1->next, *p2 = head2->next; int len1 = 0, len2 = 0; while (p1 != NULL) { len1++; p1 = p1->next; } while (p2!=NULL) { len2++; p2 = p2->next; } if (len1 >= len2) { while (len1 - len2) { p1 = p1->next; } } else { while (len2 - len1) { p2 = p2->next; } } while (p1 != p2) { p1 = p1->next; p2 = p2->next; } return p1; } int main() { int mat1[8] = { 1, 2, 3, 4, 5, 6 }; int mat2[8] = { 3, 5, 7, 8, 9, 10 }; Node* head1 = CreateList(mat1, 6); Node* head2 = CreateList(mat2, 6); Node* head_cir = CreateCirList(mat1, 6, 3); HaveCircle(head_cir); HaveCircle(head1); printf("The number of List is %d ", NodeNum(head1)); //Reverse_MTK(head); BackPrint(head1); Node* a=MergeSortedList(head1, head2); return 0; }
关于链表的环长,环起点等换在另一篇来写。