单链表常见面试题
2017-06-26 16:33
253 查看
//LinkList.h #ifndef _LINKLIST_H__ #define _LINKLIST_H__ #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> typedef int DataType; typedef struct Node { DataType data; struct Node* next; }Node,*pNode,*pList; void InitList(pList* pplist); //尾插法 void PushBack(pList* pplist); //排序 void BubbleSort(pList* pplist); //打印单向链表 void ReversePrint(pList plist); //删除无头单链表的非尾结点 void EraseNotTail(pNode pos); //在无头单链表的非头结点前插入一个元素 void InsertFrontNode(pNode pos, DataType x); //约瑟夫环问题 void JosephCycle(pList* pplist, int k); //逆序单向链表 void ReverseList(pList* pplist); //合并两个有序列表 pList Merge(const pList* p1, const pList* p2); //查找单链表的中间节点,要求只能遍历一次链表 pNode FindMidNode(pList plist); //查找单链表的倒数第k个节点,要求只能遍历一次链表 pNode FindKNode(pList plist, int k); //判断链表时候带环 pNode CheckCircle(pList plist); //求环的长度 int GetCircleLength(pNode meet); //求环的入口点 pNode GetCycleEntryNode(pList plist, pNode meet); //判断两条单项链表时候相交 int CheckCross(pList list1, pList list2); //求交点 pNode GetCrossNode(pList list1, pList list2); #endif //LinkList.c #define _CRT_SECURE_NO_WARNINGS #include"LinkList.h" pNode buynode(DataType x) { pNode tmp = NULL; tmp = (pNode)malloc(sizeof(Node)); if (tmp == NULL) { perror("malloc"); exit(1); } tmp->data = x; tmp->next = NULL; return tmp; } void InitList(pList* pplist) { assert(pplist); *pplist = NULL; } //尾插法 void PushBack(pList* pplist,DataType x) { pNode cur = NULL; assert(pplist); cur = *pplist; pNode newnode = buynode(x); if (*pplist == NULL) { *pplist = newnode; } else { while (cur->next) { cur = cur->next; } cur->next = newnode; } } //排序 void BubbleSort(pList* pplist) { pNode cur = NULL; pNode tail = NULL; assert(pplist); cur = *pplist; if (*pplist == NULL) { return; } while (cur != tail) { while (cur->next!=tail) { if (cur->data < cur->next->data) { DataType tmp = cur->data; cur->data = cur->next->data; cur->next->data = tmp; } cur = cur->next; } tail = cur; cur = *pplist; } } //打印单向链表 void Display(pList plist) { pNode tmp = plist; while (tmp) { printf("%d->", tmp->data); tmp = tmp->next; } printf("end\n"); } //查找x所在的节点 pNode Find(pList pplist,DataType x) { pNode cur = pplist; if (pplist == NULL) { return NULL; } else { while (cur) { if (cur->data == x) { return cur; } cur = cur->next; } return NULL; } } //删除无头单链表的非尾结点 void EraseNotTail(pNode pos) { pNode cur = NULL; assert(pos); cur = pos->next; pos->data = cur->data; pos->next = cur->next; free(cur); cur = NULL; } //在无头单链表的非头结点前插入一个元素 void InsertFrontNode(pNode pos, DataType x) { pNode NewNode = NULL; assert(pos); NewNode = buynode(x); NewNode fdac ->next = pos->next; pos->next = NewNode; DataType tmp = pos->data; pos->data = NewNode->data; NewNode->data = tmp; } //约瑟夫环问题 void JosephCycle(pList* pplist, int k) { } //逆序单向链表 void ReverseList(pList* pplist) { pNode cur = *pplist; pNode p = NULL; pNode r = NULL; assert(pplist); while (cur) { r = p; p = cur; cur = cur->next; p->next = r; } *pplist = p; } //合并两个有序列表 非递归 pList Merge(const pList* p1, const pList* p2) { pList newnode = NULL; pNode cur = NULL; pNode cur1 = *p1; pNode cur2 = *p2; assert(p1); assert(p2); //p1和p1相等(包括两个都为NULL) if (*p1 == *p2) { return *p1; } //一个为空,一个非空 if ((*p1 == NULL) && (*p2 != NULL)) { return *p2; } if ((*p2 == NULL) && (*p1 != NULL)) { return *p1; } //2个都不为空 if (cur1->data < cur2->data) { newnode = cur1; cur1 = cur1->next; newnode->next = NULL; } else { newnode = cur2; cur2 = cur2->next; newnode->next = NULL; } cur = newnode; while (cur1&&cur2) { if (cur1->data > cur2->data) { cur->next = cur2; cur2 = cur2->next; cur = cur->next; } else { cur->next = cur1; cur1 = cur1->next; cur = cur->next; } } if (cur1 == NULL) { cur->next = cur2; } else { cur->next = cur1; } return newnode; } //查找单链表的中间节点,要求只能遍历一次链表 pNode FindMidNode(pList plist) { pNode slow = plist; pNode fast = plist; if ((fast == NULL) || (fast->next == NULL)) { return fast; } else { while (fast&&fast->next) { fast = fast->next->next; slow = slow->next; } return slow; } } //查找单链表的倒数第k个节点,要求只能遍历一次链表 pNode FindKNode(pList plist, int k) { pNode fast = plist; pNode slow = plist; if (plist == NULL) { return NULL; } int i = 0; for (i; i < k-1; i++) { fast = fast->next; if (fast == NULL) { return NULL; } } fast = fast->next; while (fast) { fast = fast->next; slow = slow->next; } return slow; } //判断链表是否带环 pNode CheckCircle(pList plist) { pNode slow = plist; pNode fast = plist; if (plist == NULL) { return NULL; } else { while (fast&&fast->next) { fast = fast->next->next; slow = slow->next; if (fast == slow) { return slow; break; } } return NULL; } } //求环的长度 int GetCircleLength(pNode meet) { int count = 0; pNode cur = meet; do { count++; cur = cur->next; } while (cur!=meet); return count; } //求环的入口点 pNode GetCycleEntryNode(pList plist, pNode meet) { } //判断两条单项链表时候相交 int CheckCross(pList list1, pList list2) { pNode cur1 = list1; pNode cur2 = list2; if (cur1 == NULL || cur2 == NULL) { return 0; //0表示不相交,1表示相交 } while (cur1->next) { cur1 = cur1->next; } while (cur2->next) { cur2 = cur2->next; } if (cur1 == cur2) { return 1; } return 0; } //求交点 pNode GetCrossNode(pList list1, pList list2) { int len1 = 0, len2 = 0; pNode cur1 = NULL; pNode cur2 = NULL; cur1 = list1; cur2 = list2; while (cur1->next) { len1++; cur1 = cur1->next; } while (cur2->next) { len2++; cur2 = cur2->next; } int diff = abs(len2 - len1); if (len1 > len2) { cur1 = list1; cur2 = list2; } else { cur1 = list2; cur2 = list1; } for (int i = 0; i < diff; i++) { cur1 = cur1->next; } while (cur1 != cur2) { cur1 = cur1->next; cur2 = cur2->next; } return cur1; } //test.c #define _CRT_SECURE_NO_WARNINGS #include"LinkList.h" void test1() { pList pplist; InitList(&pplist); PushBack(&pplist, 1); PushBack(&pplist, 2); PushBack(&pplist, 3); PushBack(&pplist, 4); Display(pplist); //ReversePrint1(&pplist); //ReversePrint2(&pplist); Display(pplist); } void test2() { pList pplist; pNode node = NULL; InitList(&pplist); PushBack(&pplist, 1); PushBack(&pplist, 2); PushBack(&pplist, 3); PushBack(&pplist, 4); Display(pplist); node = Find(pplist, 3); EraseNotTail(node); InsertFrontNode(node, 10); Display(pplist); } void test3() { pList pplist; pNode node = NULL; InitList(&pplist); PushBack(&pplist, 11); PushBack(&pplist, 2); PushBack(&pplist, 7); PushBack(&pplist, 4); Display(pplist); BubbleSort(&pplist); Display(pplist); } void test4() { pList s1; pList s2; pList s3 = NULL; pList node = NULL; pNode mid = NULL; InitList(&s1); InitList(&s2); PushBack(&s1, 1); PushBack(&s1, 3); PushBack(&s1, 5); Display(s1); PushBack(&s2, 2); PushBack(&s2, 4); PushBack(&s2, 6); PushBack(&s2, 8); PushBack(&s2, 10); Display(s2); node = Merge(&s2, &s1); mid=FindMidNode(node); Display(node); printf("%d\n", mid->data); } void test5() { pList pplist; pNode node = NULL; InitList(&pplist); PushBack(&pplist, 11); PushBack(&pplist, 2); PushBack(&pplist, 7); PushBack(&pplist, 44); PushBack(&pplist, 5); PushBack(&pplist, 8); node= Find(pplist, 8); node->next = Find(pplist, 2); Display(pplist); node = FindKNode(pplist, 7); printf("%d\n", node->data); } void test6() { pList pplist; pNode node = NULL; pNode newnode = NULL; InitList(&pplist); PushBack(&pplist, 11); PushBack(&pplist, 2); PushBack(&pplist, 7); PushBack(&pplist, 44); PushBack(&pplist, 5); PushBack(&pplist, 8); node = Find(pplist, 8); node->next = Find(pplist, 2); newnode = CheckCircle(pplist); //printf("%d\n", newnode->data); int ret=GetCircleLength(newnode); printf("%d\n", ret); } void test7() { pList s1; pList s2; pNode node; pNode c; InitList(&s1); InitList(&s2); PushBack(&s1, 1); PushBack(&s1, 3); PushBack(&s1, 5); PushBack(&s2, 2); PushBack(&s2, 4); PushBack(&s2, 6); PushBack(&s2, 8); PushBack(&s2, 10); node = Find(s1, 5); node->next = Find(s2, 6); int ret = CheckCross(NULL, NULL); if (ret == 1) { printf("相交\n"); } else { printf("不相交\n"); } c = GetCrossNode(s1, s2); printf("%d\n", c->data); } int main() { //test1(); //test2(); //test3(); //test4(); //test5(); //test6(); test7(); system("pause"); return 0; }