本篇博客主要介绍链表的操作,较上次的链表题难,更能够锻炼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;
}
转载于:https://blog.51cto.com/10740590/1742381