c语言pop逆置单链表,C语言实现单链表

实现单链表的以下操作:

list.h:

#ifndef __LIST_H__

#define __LIST_H__

#include

#include

#include

typedef int DataType;

typedef struct Node

{

DataType _data;

struct Node *_pNext;

}Node,*pNode;

// 初始化单链表

void InitList(pNode* pHead);

// 在单链表的尾部插入一个节点

void PushBack(pNode* pHead, DataType data);

// 删除单链表的最后一个节点

void PopBack(pNode* pHead);

// 在单链表的头部插入值为data的结点

void PushFront(pNode* pHead, DataType data);

// 删除单链表的第一个结点

void PopFront(pNode* pHead);

// 在单链表中查找值为data的结点,找到了返回该结点的地址,否则返回NULL

Node* Find(pNode pHead, DataType data);

// 在单链表pos位置后插入值为data的结点

void Insert(pNode pos, DataType data);

// 在单链表中删除位置为pos的结点

void Erase(pNode* pHead, pNode pos);

// 移除单链表中第一个值为data的结点

void Remove(pNode* pHead, DataType data);

// 移除单链表中所有值为data的结点

void RemoveAll(pNode* pHead, DataType data);

// 获取单链表总结点的总个数

size_t Size(pNode pHead);

// 判断结点是否为空

DataType Empty(pNode pHead);

// 返回单链表的最后一个结点的位置

pNode Back(pNode pHead);

// 返回单链表的第一个结点的位置

pNode Front(pNode pHead);

// 构建一个新节点

Node* BuyNode(DataType data);

// 正向打印单链表

void PrintList(pNode pHead);

//单链表实现约瑟夫环

void JosiphCircle(pNode *pHead,size_t M);

///面试题//

//12.24实现无头单链表的以下操作:

// 逆序打印单链表

void PrintFromTail2Head(pNode pHead);

// 删除单链表的非尾结点(不能遍历单链表)

void DeleteNotTailNode(pNode pos);

// 使用递归实现从未到头打印单链表

void PrintFromTail2Head(pNode pHead);

// 删除单链表的非尾结点

void DeleteNotTailNode(pNode pos);

// 在单链表非头结点前插入结点data

void InsertNotHeadNode(pNode pos, DataType data);

// 查找单链表的中间结点,要求只便利一次链表

pNode FindMidNode(pNode pHead);

// 查找单链表的倒数第K个结点,要求只遍历一次链表

pNode FindLastKNode(pNode pHead, size_t k);

// 使用冒泡排序对单链表进行排序

void BubbleSort(pNode pHead);

// 判断两个单链表是否相交(链表不带环)

int IsListCross(pNode L1, pNode L2);

// 若不带环的单链表相交,求交点

pNode GetCrossNode(pNode PL1, pNode PL2);

//12.25实现链表的以下操作:

// 实现单链表的逆置:使用三个指针

pNode ReverseList(pNode pHead);

// 实现单链表的逆置:使用头插法

void ReverseList_P(pNode* pHead);

// 合并两个已序单链表,合并后依然有序

pNode MergeList(pNode pHead1, pNode pHead2);

// 判断链表是否带环,若带环给出相遇点

pNode HasCircle(pNode pHead);

// 求环的长度

size_t GetCircleLen(pNode pMeetNode);

// 求环的入口点

pNode GetEnterNode(pNode pHead, pNode pMeetNode);

// 判断链表是否相交,注意:链表可能带环

int IsCrossWithCircle(pNode pHead1, pNode pHead2);

#endif //__LIST_H__

List.c:

#include "List.h"

void InitList(pNode *pHead)

{

assert(pHead);

*pHead = NULL;

}

// 在单链表的尾部插入一个节点

void PushBack(pNode* pHead, DataType data)

{

assert(pHead);

if(*pHead == NULL)

{

*pHead = BuyNode(data);

}

else

{

Node *pTailNode = *pHead;

while(pTailNode->_pNext)

{

pTailNode = pTailNode->_pNext;

}

pTailNode->_pNext = BuyNode(data);

}

}

//构建一个新节点

static Node* BuyNode(DataType data)

{

Node *pNewNode = (Node *)malloc(sizeof(Node));

if(pNewNode != NULL)

{

pNewNode->_data = data;

pNewNode->_pNext = NULL;

}

return pNewNode;

}

//删除单链表的最后一个节点

void PopBack(pNode* pHead)

{

assert(pHead);

if(pHead == NULL)

{

return;

}

else if((*pHead)->_pNext == NULL)

{

free(*pHead);

*pHead = NULL;

}

else

{

Node *pPreNode = *pHead;

Node *pTailNode = *pHead;

while(pTailNode->_pNext)

{

pPreNode = pTailNode;

pTailNode = pTailNode->_pNext;

}

free(pTailNode);

pPreNode->_pNext = NULL;

}

}

// 正向打印单链表

void PrintList(pNode pHead)

{

Node *pCurNode = pHead;

while(pCurNode)

{

printf("%d->",pCurNode->_data);

pCurNode = pCurNode->_pNext;

}

printf("NULL\n");

}

// 在单链表的头部插入值为data的结点

void PushFront(pNode* pHead, DataType data)

{

assert(pHead);

if(*pHead == NULL)

{

*pHead = BuyNode(data);

}

else

{

pNode pNewNode = BuyNode(data);

pNewNode->_pNext = *pHead;

*pHead = pNewNode;

}

}

// 删除单链表的第一个结点

void PopFront(pNode* pHead)

{

assert(pHead);

if(*pHead == NULL)

{

return;

}

else if((*pHead)->_pNext == NULL)

{

free(*pHead);

*pHead = NULL;

}

else

{

Node *pDelNode = *pHead;

*pHead = (*pHead)->_pNext;

free(pDelNode);

}

}

// 在单链表中查找值为data的结点,找到了返回该结点的地址,否则返回NULL

Node* Find(pNode pHead, DataType data)

{

Node *pCurNode = pHead;

while(pCurNode)

{

if(pCurNode->_data == data)

{

return pCurNode;

}

pCurNode = pCurNode->_pNext;

}

return NULL;

}

//在单链表pos位置后插入值为data的结点

void Insert(pNode pos, DataType data)

{

Node *pNewNode = NULL;

if(pos == NULL)

{

return;

}

pNewNode = BuyNode(data);

if(pNewNode == NULL)

{

return;

}

pNewNode->_pNext = pos->_pNext;

pos->_pNext = pNewNode;

}

// 在单链表非头结点前插入结点data

void InsertNotHeadNode(pNode pos, DataType data)

{

pNode pNewNode = BuyNode(pos->_data);

if(pNewNode == NULL)

{

return;

}

pNewNode->_pNext = pos->_pNext;

pos->_pNext = pNewNode;

pos->_data = data;

}

//在单链表中删除位置为pos的结点

void Erase(pNode* pHead, pNode pos)

{

assert(pHead);

if(NULL == *pHead || NULL == pos)

{

return;

}

else if(*pHead == pos)

{

PopFront(pHead);

}

else

{

Node *pPreNode = *pHead;

while(pPreNode->_pNext != pos)

{

pPreNode = pPreNode->_pNext;

}

pPreNode->_pNext = pos->_pNext;

free(pos);

}

}

//移除单链表中第一个值为data的结点(非尾结点)

void Remove(pNode* pHead, DataType data)

{

pNode pPreNode = Find(*pHead,data);

if(pPreNode == NULL)

{

return;

}

else

{

pNode pDelNode = pPreNode->_pNext;

pPreNode->_data = pPreNode->_pNext->_data;

pPreNode->_pNext = pPreNode->_pNext->_pNext;

free(pDelNode);

}

}

//移除单链表中第一个值为data的结点

void Remove(pNode* pHead, DataType data)

{

pNode pPreNode = Find(*pHead,data);

assert(pHead);

if(pPreNode == NULL)

{

return;

}

else

{

Erase(pHead,pPreNode);

}

}

//移除单链表中所有值为data的结点(递归)

void RemoveAll(pNode* pHead, DataType data)

{

pNode pDelNode = NULL;

Remove(pHead,data);

pDelNode = Find(*pHead,data);

if(pDelNode == NULL)

{

return;

}

else

{

RemoveAll(pHead,data);

}

}

//移除单链表中所有值为data的结点

void RemoveAll(pNode* pHead, DataType data)

{

pNode pPre = *pHead;

pNode pCur = *pHead;

pCur = pPre->_pNext;

if(*pHead == NULL)

{

return;

}

while(pCur)

{

if(pCur->_data == data)

{

pPre->_pNext = pCur->_pNext;

free(pCur);

pCur = pPre->_pNext;

}

else

{

pPre = pCur;

pCur = pCur->_pNext;

}

}

if((*pHead)->_data == data)

{

pNode pTemp = *pHead;

*pHead = pTemp->_pNext;

free(pTemp);

}

}

//移除单链表中所有值为data的结点(非尾结点)

void RemoveAll(pNode* pHead, DataType data)

{

pNode pPreNode = *pHead;

while(pPreNode)

{

pPreNode = Find(pPreNode,data);

if(pPreNode == NULL)

{

return;

}

else

{

pNode pDelNode = pPreNode->_pNext;

pPreNode->_data = pPreNode->_pNext->_data;

pPreNode->_pNext = pPreNode->_pNext->_pNext;

free(pDelNode);

}

}

}

//删除单链表的非尾结点(不能遍历单链表)

void DeleteNotTailNode(pNode pos)

{

assert(pos);

if(pos->_pNext == NULL)

{

return;

}

else

{

pNode pDelNode = pos->_pNext;

pos->_data = pDelNode->_data;

pos->_pNext = pDelNode->_pNext;

free(pDelNode);

}

}

//逆序打印单链表

void PrintFromTail2Head(pNode pHead)

{

if(pHead == NULL)

{

return;

}

else

{

PrintFromTail2Head(pHead->_pNext);

printf("%d->",pHead->_data);

}

}

//获取单链表总结点的总个数

size_t Size(pNode pHead)

{

int count = 0;

pNode pPreNode = pHead;

while(pPreNode)

{

count++;

pPreNode = pPreNode->_pNext;

}

return count;

}

// 判断结点是否为空

DataType Empty(pNode pHead)

{

if(pHead == NULL)

{

return 0;

}

else

return 1;

}

//返回单链表的最后一个结点的位置

pNode Back(pNode pHead)

{

pNode pTailNode = pHead;

while(pTailNode->_pNext)

{

pTailNode = pTailNode->_pNext;

}

return pTailNode;

}

//返回单链表的第一个结点的位置

pNode Front(pNode pHead)

{

return pHead;

}

//单链表实现约瑟夫环

void JosiphCircle(pNode *pHead,size_t M)

{

int m = M;

pNode pCurNode = NULL;

assert(pHead);

if(*pHead == NULL)

{

return;

}

pCurNode = *pHead;

while(pCurNode != pCurNode->_pNext)

{

pNode pDelNode = NULL;

m = M;

while(--m)

{

pCurNode = pCurNode->_pNext;

}

pDelNode = pCurNode->_pNext;

pCurNode->_data = pDelNode->_data;

pCurNode->_pNext = pDelNode->_pNext;

free(pDelNode);

}

*pHead = pCurNode;

(*pHead)->_pNext = NULL;

}

// 查找单链表的中间结点,要求只遍历一次链表

pNode FindMidNode(pNode pHead)

{

pNode pFast = NULL;

pNode pSlow = NULL;

if(pHead == NULL)

{

return NULL;

}

pFast = pHead;

pSlow = pHead;

while(pFast && pFast->_pNext)

{

pSlow = pSlow->_pNext;

pFast = pFast->_pNext->_pNext;

}

return pSlow;

}

// 查找单链表的倒数第K个结点,要求只遍历一次链表

pNode FindLastKNode(pNode pHead, size_t k)

{

pNode pFast = NULL;

pNode pSlow = NULL;

if(pHead == NULL || k == 0)

{

return NULL;

}

pFast = pHead;

pSlow = pHead;

while(k--)

{

pFast = pFast->_pNext;

}

while(pFast)

{

pFast = pFast->_pNext;

pSlow = pSlow->_pNext;

}

return pSlow;

}

// 使用冒泡排序对单链表进行排序

void BubbleSort(pNode pHead)

{

pNode pTailNode = NULL;

pNode pPre = NULL;

pNode pCur = NULL;

int flag = 0;

if(pHead == NULL || pHead->_pNext == NULL)

{

return;

}

pPre = pHead;

pCur = pHead;

while(pHead != pTailNode)

{

pPre = pHead;

pCur = pPre->_pNext;

while(pCur != pTailNode)

{

if(pPre->_data > pCur->_data)

{

DataType temp = 0;

flag = 1;

temp = pPre->_data;

pPre->_data = pCur->_data;

pCur->_data = temp;

}

pPre = pCur;

pCur = pCur->_pNext;

}

if(flag == 0)

{

return;

}

pTailNode = pPre;

}

}

// 判断两个单链表是否相交(链表不带环)

int IsListCross(pNode L1, pNode L2)

{

pNode pCurNode1 = NULL;

pNode pCurNode2 = NULL;

if(L1 == NULL || L2 == NULL)

{

return 0;

}

pCurNode1 = L1;

pCurNode2 = L2;

while(pCurNode1->_pNext)

{

pCurNode1 = pCurNode1->_pNext;

}

while(pCurNode2->_pNext)

{

pCurNode2 = pCurNode2->_pNext;

}

if(pCurNode1 == pCurNode2)//两不带环的单链表相交尾节点必相同

{

return 1;

}

else

return 0;

}

// 若不带环的单链表相交,求交点

pNode GetCrossNode(pNode pL1, pNode pL2)

{

size_t s1 = 0;

size_t s2 = 0;

int gap = 0;

if(IsListCross(pL1,pL2) == 0)

{

return NULL;

}

s1 = Size(pL1);

s2 = Size(pL2);

gap = s1 - s2;

if(gap < 0)

{

gap = -gap;

while(gap--)

{

pL2 = pL2->_pNext;

}

}

else

{

while(gap--)

{

pL1 = pL1->_pNext;

}

}

while(pL1 != pL2)

{

pL1 = pL1->_pNext;

pL2 = pL2->_pNext;

}

return pL1;

}

// 实现单链表的逆置:使用三个指针

pNode ReverseList(pNode pHead)

{

pNode pPreNode = NULL;

pNode pCurNode = NULL;

pNode pNextNode = NULL;

if(pHead == NULL || pHead->_pNext == NULL)

{

return NULL;

}

pPreNode = pHead;

pCurNode = pPreNode->_pNext;

pNextNode = pCurNode->_pNext;

while(pNextNode)

{

pCurNode->_pNext = pPreNode;

pPreNode = pCurNode;

pCurNode = pNextNode;

pNextNode = pNextNode->_pNext;

}

pCurNode->_pNext = pPreNode;

pHead->_pNext = NULL;

pHead = pCurNode;

return pHead;

}

// 实现单链表的逆置:使用头插法

void ReverseList_P(pNode* pHead)

{

pNode pNewHead = NULL;

pNode pPreNode = NULL;

pNode pCurNode = NULL;

if(*pHead == NULL || (*pHead)->_pNext == NULL)

{

return;

}

pPreNode = *pHead;

pCurNode = (*pHead)->_pNext;

while(pCurNode)

{

pPreNode->_pNext = pNewHead;

pNewHead = pPreNode;

pPreNode = pCurNode;

pCurNode = pCurNode->_pNext;

}

pPreNode->_pNext = pNewHead;

pNewHead = pPreNode;

*pHead = pNewHead;

}

// 合并两个已序单链表,合并后依然有序

pNode MergeList(pNode pHead1, pNode pHead2)

{

pNode pL1 = NULL;

pNode pL2 = NULL;

pNode pNewHead = NULL;

pNode pTailNode = NULL;

if(pHead1 == NULL)

{

return pHead2;

}

if(pHead2 == NULL)

{

return pHead1;

}

pL1 = pHead1;

pL2 = pHead2;

if(pL1->_data <= pL2->_data)

{

pNewHead = pL1;

pTailNode = pNewHead;

pL1 = pL1->_pNext;

}

else

{

pNewHead = pL2;

pTailNode = pNewHead;

pL2 = pL2->_pNext;

}

while(pL1 && pL2)

{

if(pL1->_data <= pL2->_data)

{

pTailNode->_pNext = pL1;

pL1 = pL1->_pNext;

}

else

{

pTailNode->_pNext = pL2;

pL2 = pL2->_pNext;

}

pTailNode = pTailNode->_pNext;

}

if(pL1 != NULL)

{

pTailNode->_pNext = pL1;

}

if(pL2 != NULL)

{

pTailNode->_pNext = pL2;

}

return pNewHead;

}

// 判断链表是否带环,若带环给出相遇点

pNode HasCircle(pNode pHead)

{

pNode pFast = NULL;

pNode pSlow = NULL;

if(pHead == NULL)

{

return NULL;

}

pFast = pHead;

pSlow = pHead;

//环内点都是相遇点

while(pFast && pFast->_pNext)

{

pSlow = pSlow->_pNext;

pFast = pFast->_pNext->_pNext;

if(pSlow == pFast)

{

return pSlow;

}

}

return NULL;

}

// 求环的长度

size_t GetCircleLen(pNode pMeetNode)

{

pNode pCurNode = pMeetNode;

size_t count = 1;

while(pCurNode->_pNext != pMeetNode)

{

pCurNode = pCurNode->_pNext;

count++;

}

return count;

}

// 求环的入口点

pNode GetEnterNode(pNode pHead, pNode pMeetNode)

{

pNode pH = NULL;

pNode pM = NULL;

if(pHead == NULL || pMeetNode == NULL)

{

return NULL;

}

pH = pHead;

pM = pMeetNode;

while(pH != pM)

{

pH = pH->_pNext;

pM = pM->_pNext;

}

return pH;

}

// 判断链表是否相交,注意:链表可能带环

//(两个链表都带环或都不带环)

int IsCrossWithCircle(pNode pHead1, pNode pHead2)

{

pNode pMeetNode1 = HasCircle(pHead1);

pNode pMeetNode2 = HasCircle(pHead2);

if(pMeetNode1 == NULL && pMeetNode2 == NULL)

{

pNode pCurNode1 = pHead1;

pNode pCurNode2 = pHead2;

if(pHead1 == NULL || pHead2 == NULL)

{

return 0;

}

while(pCurNode1->_pNext)

{

pCurNode1 = pCurNode1->_pNext;

}

while(pCurNode2->_pNext)

{

pCurNode2 = pCurNode2->_pNext;

}

if(pCurNode1 == pCurNode2)

{

return 1; //不带环相交

}

}

else if(pMeetNode1 != NULL && pMeetNode2 != NULL)

{

pNode pCurNode = pMeetNode1;

while(pCurNode->_pNext != pMeetNode1)

{

if(pCurNode == pMeetNode2)

{

return 2; //带环环外相交

}

pCurNode = pCurNode->_pNext;

}

if(pCurNode == pMeetNode2)

{

return 2; //带环环内相交(环的入口点相交)

}

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值