1.单链表实现约瑟夫环(JosephCircle)
思路:首先约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
代码如下:
sListNode * JocephCircle(sListNode *pFirst, int k)
{
assert(pFirst);
sListNode*pPrev = NULL;
sListNode *pNode = pFirst;
int i = 0;
//将单链表改成循坏链表
while (pNode->pNext)
{
pNode = pNode->pNext;
}
pNode->pNext = pFirst;
//开始执行
pNode = pFirst;
while (pNode->pNext!=pNode)
{
//找出第k个节点
for (i = 0; i < k - 1; i++)
{
pPrev = pNode;
pNode = pNode->pNext;
}
pPrev->pNext = pNode->pNext;
free(pNode);
pNode = pPrev->pNext;
}
return pNode;
}
2.求两个已排序单链表中相同的数据
代码如下:
void UnionSet(sListNode *s1, sListNode *s2)
{
assert(s1);
assert(s2);
sListNode *p1 = s1;
sListNode *p2 = s2;
while (p1 != NULL&&p2 != NULL)
{
if (p1->data <p2->data)
{
p1 = p1->pNext;
}
else if (p1->data>p2->data)
{
p2 = p2->pNext;
}
else
{
printf("%d ", p1->data);
p1 = p1->pNext;
p2 = p2->pNext;
}
}
}
3.复制链表。一个链表的每个节点,有一个next指针指向下一个节点,还有一个random指针指向这个链表的一个随机节点或者NULL,复制这个链表,返回复制后的新链表
主要分三步:
- 复制新结点放在老结点后边
- 复制random
- 拆链表
代码如下:
ListNode *ListRandom(ListNode *pFirst)
{
assert(pFirst);
ListNode *pNode;
ListNode *pNewNode;
ListNode *pOldRandom;
ListNode *pNewRandom;
//1.复制结点放在老结点后边
for (pNode = pFirst; pNode != NULL; pNode = pNode->pNext->pNext){
pNewNode = (ListNode *)malloc(sizeof(ListNode));
pNewNode->data = pNode->data;
pNewNode->pNext = pNode->pNext;
pNode->pNext = pNewNode;
}
//2.复制random
for (pNode = pFirst; pNode != NULL; pNode = pNode->pNext->pNext){
pNewNode = pNode->pNext;
pOldRandom = pNode->random;
if (pOldRandom != NULL){
pNewRandom = pOldRandom->pNext;
pNewNode->random = pNewRandom;
}
}
//3.拆链表
ListNode *pNewFirst = pFirst -> pNext;
for (pNode = pFirst; pNode != NULL; pNode = pNode->pNext->pNext){
pNewNode = pNode->pNext;
pNode->pNext = pNewNode->pNext;
if (pNode->pNext != NULL){
pNewNode->pNext = pNode->pNext->pNext;
}
else
{
pNewNode->pNext = NULL;
}
return pNewNode;
}
}