本篇博客主要介绍链表的操作,较上次的链表题难,更能够锻炼C语言的编程能力,对以后的面试有很大的帮助。内容主要包括单链表实现约瑟夫环,链表的排序,合并两个有序链表,判断链表是否带环并且计算环的长度等问题。
建立链表节点:
typedef int Datatype; typedef struct SListNode { Datatype Data; SListNode *next; }SListNode;
——下面主要具体的程序实现(注释对代码的理解)
//链表的基本操作2 //单链表实现约瑟夫环 SListNode * JoseCycle(SListNode * pHead, int k) { if (pHead == NULL) //先进行链表判空操作 { return NULL; } SListNode *cur = pHead; while (1) { if (cur->next == cur) { return cur; } int count = k-1; //执行k-1次 while (count--) { cur = cur->next; } //替换法进行删除 SListNode *next = cur->next; cur->Data = next->Data; cur->next = next->next; free(next); } } //单链表的冒泡排序 void BubbleSort(SListNode *pHead) { if (pHead == NULL || pHead->next == NULL) { return ; } SListNode *tail = pHead; while (tail) //使用两次循环进行冒泡控制 { SListNode *cur = pHead; SListNode *next = pHead->next; while (next) { if (cur->Data > next->Data) { Datatype tmp = cur->Data; cur->Data = next->Data; next->Data = tmp; cur = cur->next; next = next->next; } tail = tail->next; } } } //合并两个有序单链表,使得链表仍有序 SListNode *MergeList(SListNode * L1, SListNode *L2) { if (L1 == NULL) //先考虑L1和L2为空的情况,进行处理 { return L2; } if (L2 == NULL) { return L1; } SListNode * newHead; //创建新的链表 SListNode *pHead1 = L1; SListNode *pHead2 = L2; if (pHead1->Data < pHead2->Data) //确定新链表的头节点 { newHead = pHead1; pHead1 = pHead1->next; } else { newHead = pHead2; pHead2 = pHead2->next; } SListNode *tail = NULL; while (pHead1 && pHead2) //将两个指针指向的内容相比较,摘掉较小的连接到新的链表中 { if (pHead1->Data < pHead2->Data) { tail->next = pHead1; } else { tail->next = pHead2; pHead2 = pHead2->next; } tail = tail->next; } if (pHead1) //将另一个有剩余节点的链表,直接连接到新的链表上 { tail->next = pHead1; } else if (pHead2) { tail->next = pHead2; } return newHead; } //释放节点 void DestoryList(SListNode *pHead) { SListNode *cur = pHead; while (cur) { SListNode *tmp = cur; cur = cur->next; free(tmp); } pHead = NULL; } //判断链表是否带环?求环的长度? SListNode *checkCycle(SListNode *pHead) { SListNode *slow = pHead; //利用快慢指针的方式 SListNode *fast = pHead; while (fast && fast->next) { slow = slow->next; fast = fast->next->next; if (fast == slow) //若快指针和慢指针相遇,则链表中带环 { return fast; } } return NULL; } //求环的长度 int GetCycleLength(SListNode *ptr) { assert(ptr); //先对指针进行判空 SListNode *cur = ptr; int count = 0; do { ++count; cur = cur->next; } while (cur != ptr); //利用计数器的方式进行计数 return count; }