您的位置:首页 > 编程语言 > C语言/C++

【C语言】链表 题

2016-04-10 21:03 357 查看

Slist.h

#pragma once

#include <stdio.h>
#include <assert.h>
#include <malloc.h>

typedef int DataType;

typedef struct ListNode
{
DataType data;
struct ListNode *pNext;
}SListNode, *PSListNode;

//初始化单链表(对于无头结点单链表,该函数没有意义)
void InitList(PSListNode* pHead);

// 销毁单链表
void DestroyList(PSListNode* pHead);

// 尾插
void PushBack(PSListNode* pHead, DataType data);

// 尾出
void PopBack(PSListNode* pHead);

// 头插
void PushFront(PSListNode* pHead, DataType data);

// 头出
void PopFront(PSListNode* pHead);

// 查找元素data
PSListNode Find(PSListNode pHead, DataType data);

// 删除pos位置的结点
void  Erase(PSListNode* pHead, PSListNode pos);

// 在链表的pos位置插入元素data
void  Insert(PSListNode* pHead, PSListNode pos, DataType data);

//打印
void PrintList(PSListNode pHead);

// 从头至尾打印单链表
void PrintListTailToHead(PSListNode pHead);

// 链表的非头结点前插入元素data
void InsertNotHead(PSListNode pos, DataType data);

// 删除链表的非尾结点
void DelNotTailNode(PSListNode pos);

// 查找链表的中间结点,要求只遍历一次链表
PSListNode FindMidNode(PSListNode pHead);

// 约瑟夫环问题
PSListNode JosephusCircle(PSListNode pHead, int M);

//反转(逆置)单链表
void ReverseList(PSListNode *pHead);

//冒泡排序链表
void BubbleSort(PSListNode pHead);

//合并两个有序链表
PSListNode MergeList(PSListNode pList1, PSListNode pList2);

//删除链表的倒数第K个结点
void DelNodeK(PSListNode* pHead, int K);

//求环的长度
int GetCyleLen(PSListNode pMeetNode);

// 判断链表是否带环,若带环返回环入口点
PSListNode CheckCycle(PSListNode pHead);

//获取环入口点
PSListNode GetCircleEntryNode(PSListNode pHead, PSListNode pMeetNode);

//判断两个链表是否相交,假设两个链表都不带环
int CheckCross(PSListNode pList1Head, PSListNode pList2Head);

//判断两个链表是否相交
int IsListCroseWithCycle(PSListNode pL1, PSListNode pL2);

SList.c

#include "SList.h"

//初始化
void InitList(PSListNode* pHead)
{
*pHead = NULL;
}

//打印
void PrintList(PSListNode pHead)
{
PSListNode pCurNode = pHead;
while(pCurNode)
{
printf("%d->", pCurNode->data);
pCurNode = pCurNode->pNext;
}
printf("NULL\n");
}

PSListNode BuyNode(DataType data)
{
PSListNode pTemp = (PSListNode)malloc(sizeof(SListNode));
if(NULL == pTemp)
{
return NULL;
}
pTemp->data = data;
pTemp->pNext = NULL;
return pTemp;
}

//尾插
void PushBack(PSListNode* pHead, DataType data)
{
PSListNode pNode = *pHead;
if (NULL == *pHead)//当链表是空链表时
{
*pHead = BuyNode(data);
}
else
{
while(pNode->pNext)
{
pNode = pNode->pNext;
}

pNode->pNext = BuyNode(data);
}
}

// 尾出
void PopBack(PSListNode* pHead)
{
PSListNode pCurNode = *pHead;//当前结点
PSListNode pPreNode = pCurNode;//前一个结点
assert(pHead);
if(NULL == *pHead)
{
return;
}
else if((*pHead)->pNext == NULL)//只有一个结点的情况
{
free(*pHead);
*pHead = NULL;
return;
}
while (pCurNode->pNext)//找尾
{
pPreNode = pCurNode;
pCurNode = pPreNode->pNext;
}

free(pCurNode);
pPreNode->pNext = NULL;
}

//头插
void PushFront(PSListNode* pHead, DataType data)
{
PSListNode pNewNode = NULL;
assert(pHead);
if(NULL == *pHead)
{
return;
}
pNewNode = BuyNode(data);
if(pNewNode != NULL)
{
pNewNode->pNext = *pHead;
*pHead = pNewNode;
}
}

// 头出
void PopFront(PSListNode* pHead)
{
PSListNode pCurNode = *pHead;
assert(pHead);
if(NULL == *pHead)
{
return;
}
*pHead = pCurNode->pNext;
free(pCurNode);
}

// 查找元素data
PSListNode Find(PSListNode pHead, DataType data)
{
PSListNode pCurNode = pHead;
while(pCurNode)
{
if(data == pCurNode->data)
{
return pCurNode;
}
pCurNode = pCurNode->pNext;
}
return NULL;
}

// 删除pos位置的结点
void  Erase(PSListNode* pHead, PSListNode pos)
{
PSListNode pPreNode = *pHead;
assert(pHead);
assert(pos);
if(NULL == *pHead)
{
return;
}
if(pos == *pHead)//如果pos是头结点
{
*pHead =pos->pNext;
free(pos);
return;
}
while (pPreNode)
{
if(pPreNode->pNext == pos)
{
pPreNode->pNext = pos->pNext;
free(pos);
return;
}
pPreNode = pPreNode->pNext;
}
}

// 在链表的pos位置插入元素data
void  Insert(PSListNode* pHead, PSListNode pos, DataType data)
{
PSListNode pNewNode = NULL;
assert(pHead);
assert(pos);
if(NULL == *pHead)
{
return;
}
pNewNode = BuyNode(data);
if(NULL != pNewNode)
{
pNewNode->pNext = pos->pNext;
pos->pNext = pNewNode;
}
}

//销毁
void DestroyList(PSListNode* pHead)
{
PSListNode pPreNode = NULL;
PSListNode pCurNode = NULL;
assert(pHead);
pCurNode = *pHead;
while (pCurNode)
{
pPreNode = pCurNode;
pCurNode = pCurNode->pNext;
free(pPreNode);
}
*pHead =NULL;
}

// 从头至尾打印单链表
void PrintListTailToHead(PSListNode pHead)
{
if(NULL != pHead)
{
PrintListTailToHead(pHead->pNext);
printf("%d", pHead->data);
}
}

// 链表的非头结点前插入元素data
void InsertNotHead(PSListNode pos, DataType data)
{
PSListNode pNewNode = NULL;
assert(pos);
pNewNode = BuyNode(data);
if(NULL != pNewNode)
{
pNewNode->pNext = pos->pNext;
pos->pNext = pNewNode;
pos->data = data;
}
}

// 删除链表的非尾结点
void DelNotTailNode(PSListNode pos)
{
PSListNode pDelNode = NULL;
assert(pos);
assert(pos->pNext);
pDelNode = pos->pNext;
pos->data = pDelNode->pNext->data;
pos->pNext = pDelNode->pNext;
free(pDelNode);
}

// 查找链表的中间结点,要求只遍历一次链表
PSListNode FindMidNode(PSListNode pHead)
{
PSListNode pFast = pHead;
PSListNode pSlow = pHead;
while((pFast != NULL)&&(pFast->pNext != NULL))
{
pFast = pFast->pNext->pNext;
pSlow = pSlow->pNext;
}
return pSlow;
}

//约瑟夫环问题
PSListNode JosephusCircle(PSListNode pHead, int M)
{
PSListNode pNode = pHead;
PSListNode pDelNode = NULL;
int K = M;
if((NULL == pHead)||(M <= 0))
{
return NULL;
}

while(pNode->pNext != pNode)
{
K = M;
while(--K)
{
pNode = pNode->pNext;
}
pDelNode = pNode->pNext;
pNode->data = pDelNode->pNext->data;
pNode->pNext = pDelNode->pNext;
free(pDelNode);
}
return pNode;
}

//反转(逆置)单链表
void ReverseList(PSListNode *pHead)
{
PSListNode pPreNode = NULL;
PSListNode pCurNode = NULL;
PSListNode pNewHead = NULL;
assert(pHead);
if((NULL == *pHead)||(NULL == (*pHead)->pNext))
{
return;
}
pCurNode = *pHead;
while(pCurNode)
{
pPreNode = pCurNode;
pCurNode = pCurNode->pNext;
pPreNode->pNext = pNewHead;
pNewHead = pPreNode;
}
*pHead = pNewHead;
}

//冒泡排序链表
void BubbleSort(PSListNode pHead)
{
PSListNode pNode = NULL;
PSListNode pTailNode = NULL;
if(NULL == pHead)
{
return;
}
while(pHead != pTailNode)
{
pNode = pHead;
while(pNode->pNext != pTailNode)
{
if(pNode->data < pNode->pNext->data)
{
DataType temp = pNode->data;
pNode->data = pNode->pNext->data;
pNode->pNext->data = temp;
}
pNode = pNode->pNext;
}
pTailNode = pNode;
}
}

//合并两个有序链表
PSListNode MergeList(PSListNode pList1Head, PSListNode pList2Head)
{
PSListNode pNewHead = NULL;
PSListNode pList1Node = pList1Head;
PSListNode pList2Node = pList2Head;
PSListNode pNode = NULL;
PSListNode pTailNode = NULL;
if(NULL == pList1Head)//List1为空链表时
{
return pList2Head;
}
if(NULL == pList2Head)//List2为空链表时
{
return pList1Head;
}
if (pList1Node->data < pList2Node->data)
{
pNode = pList1Node;
pList1Node = pList1Node->pNext;
}
else
{
pNode = pList2Node;
pList2Node = pList2Head->pNext;
}
pNewHead = pNode;
pTailNode = pNode;
while(pList1Node && pList2Node)
{
if(pList1Node->data < pList2Node->data)
{
pNode = pList1Node;
pList1Node = pList1Node->pNext;
}
else
{
pNode = pList2Node;
pList2Node = pList2Node->pNext;
}
pTailNode->pNext = pNode;
pTailNode = pTailNode->pNext;
}
if(NULL == pList1Node)
{
pTailNode->pNext = pList2Node;
}
else
{
pTailNode->pNext = pList1Node;
}
return pNewHead;
}

//删除链表的倒数第K个结点
void DelNodeK(PSListNode* pHead, int K)
{
PSListNode pFast = NULL;
PSListNode pSlow = NULL;
if((pHead == NULL)||(K <= 0))
{
return;
}
pFast = *pHead;
pSlow = *pHead;
while(--K)
{
if(pFast == NULL)
{
return;
}
pFast = pFast->pNext;
}
while(pFast->pNext)
{
pFast = pFast->pNext;
pSlow = pSlow->pNext;
}
Erase(pHead, pSlow);
}

//求环的长度
int GetCyleLen(PSListNode pMeetNode)
{
int iLen = 1;
PSListNode pNode = NULL;
if(NULL == pMeetNode)
{
return 0;
}
while(pNode->pNext != pMeetNode)
{
iLen++;
}
return iLen;
}

// 判断链表是否带环,若带环返回相遇结点
PSListNode CheckCycle(PSListNode pHead)
{
PSListNode pFast = NULL;
PSListNode pSlow = NULL;
if(NULL == pHead)
{
return NULL;
}
while((pFast)&&(pFast->pNext))
{
pFast = pFast->pNext->pNext;
pSlow = pSlow->pNext;
if(pFast == pSlow)
{
return pSlow;
}
}
return NULL;
}

//获取环入口点
PSListNode GetCircleEntryNode(PSListNode pHead, PSListNode pMeetNode)
{
PSListNode pNode1 = pHead;
PSListNode pNodeM = pMeetNode;
if (pHead == NULL || pMeetNode == NULL)
{
return NULL;
}

while (pNode1 != pNodeM)
{
pNode1 = pNode1->pNext;
pNodeM = pNodeM->pNext;
}

return pNode1;
}

//判断两个链表是否相交(假设两个链表都不带环)
int CheckCross(PSListNode pList1Head, PSListNode pList2Head)
{
PSListNode pList1Node = pList1Head;
PSListNode pList2Node = pList2Head;
if((NULL == pList1Head)||(NULL == pList2Head))
{
return 0;
}
while (pList1Node->pNext)
{
pList1Node = pList1Node->pNext;
}
while(pList2Node->pNext)
{
pList2Node = pList2Node->pNext;
}
if(pList1Node == pList2Node)
{
return 1;//相交
}
return 0;//不相交
}

//判断两个链表是否相交
int IsListCroseWithCycle(PSListNode pList1Head, PSListNode pList2Head)
{
PSListNode pList1MeetNode = NULL;
PSListNode pList2MeetNode = NULL;
PSListNode pList1Node =pList1Head;
PSListNode pList2Node = pList2Head;
if ((NULL == pList1Head)||(NULL == pList2Head))
{
return 0;
}
pList1MeetNode = CheckCycle(pList1Head);
pList2MeetNode = CheckCycle(pList2Head);
if((NULL == pList1MeetNode)||(NULL == pList2MeetNode))//都不带环
{
while(pList1Node->pNext)
{
pList1Node = pList1Node->pNext;
}
while(pList2Node->pNext)
{
pList2Node = pList2Node->pNext;
}
if(pList1Node == pList2Node)
{
return 1;//相交
}
return 0;//不相交
}
if((NULL != pList1MeetNode)||(NULL != pList2MeetNode))//都带环
{
PSListNode pNode = pList1MeetNode;
while(pNode->pNext != pList1MeetNode)
{
if(pNode == pList2MeetNode)
{
return 1;
}
pNode = pNode->pNext;
}
if(pNode == pList2MeetNode)
{
return 1;
}
return 0;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: