实现单链表的以下操作:

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;

}

c语言pop逆置单链表,C语言实现单链表相关推荐

  1. C语言实验——逆置正整数 Time Limit: 1000 ms Memory Limit: 65536 KiB 1189

    C语言实验--逆置正整数 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 输入一个三位正整数,将它反向输出. Input ...

  2. java实现单链表就地逆置,20. 微软面试题:单链表就地逆放

    题目是:链表操作,单链表就地逆置 分析: 这题只需要设置三个指针就搞定了,ListNode* p 表示当前指针, ListNode* fp: 上一个节点指针, ListNode * ep :下一个节点 ...

  3. C++ 头插法建立单链表,单链表原地逆置以及尾插法建立单链表

    #include <iostream> #include <stdlib.h> #include <cstdio> typedef int ElemType; us ...

  4. 逆置单链表c语言程序,逆置单链表C语言

    /*10.2-7-2011-05-08-19.40.c -- 第十章第二节第七题*/ #include #include /*明显常量定义*/ #define FALSE (0) #define TR ...

  5. c语言内容逆置程序设计,C语言程序设计练习题含程序及参考答案.docx

    C语言练习题 (所提供的源程序均采用自定义函数方式解决,如不采 用函数方式,也可直接在main函数中借鉴该思想编程, 因时间有限,所有程序未能一一-验证,仅供参考使用) 1定义一个函数intfun(i ...

  6. C语言数组fun函数逆置数组元素,C语言

    第一套 1. 程序填空 程序通过定义学生结构体数组,存储了若干个学生的学号.姓名和三门课的成绩.函数fun的功能是将存放学生数据的结构体数组,按照姓名的字典序(从小到大排序).请在程序的下划线处填入正 ...

  7. c语言字符串逆置,字符串逆置

    满意答案 9n7j5j3m4o 2013.12.03 采纳率:49%    等级:11 已帮助:15198人 47911 zxl0714 1358 Accepted 164K 15MS G++ 0.4 ...

  8. c语言如何输出0,怎么用c语言打印逆置整数,零不输出?

    MinRam 只是大概思路,代码并未作测试.存储后输出:按照整数来处理:int num,temp; scanf("%d",&num); if(num<0){      ...

  9. c语言io口置1,AVR C语言编程的小技巧-IO口置位

    avr AVR C语言编程的小技巧-IO口置位 给单片机IO口置位是编程用的比较多的操作,这是我在学习C语言编程中的一点小小心得,希望大家觉得有用! AVR 单片机的IO口是标准的双向端口,首先要设置 ...

最新文章

  1. Axis-Parallel Rectangle
  2. 使用VMware VSphere WebService SDK进行开发 (四)——获取集群(Cluster, ComputeResource)的相关信息
  3. pandas loc 正则匹配字符串_一场pandas与SQL的巅峰大战(二)
  4. 开源.Net Standard版华为物联网北向接口SDK
  5. 十天学Linux内核之第七天---电源开和关时都发生了什么
  6. Android applicationId与包名的区别
  7. 重做系统,出现invalid switch noid
  8. Qt中的串口编程之一
  9. python之小坑:IndentationError: expected an indented block
  10. win10虚拟机连接不上内网服务器,win10系统虚拟机无法连接网络的解决方法
  11. 小米怎么快速回到顶部_打开小米这3个设置,手机越用越好用啦!你现在还不知道吗?...
  12. 计算机强制关机后重启报错,电脑开起来就自动关机
  13. idea 集成Git 遇到的问题 与解决
  14. RSD 教程 —— §2.2  第1次运行的配置
  15. 2010考研数学二第(11)题——高阶导数
  16. App开发智能车载应用之概述篇
  17. 记录一下tomcat的./startup.sh完成之后没有tomcat进程问题
  18. 无线ap死机无法联接服务器,无法连接无线接入点 这几步帮你轻松解决无线连接问题...
  19. CLA not signed yet
  20. 二十一世纪大学英语读写基础教程学习笔记(原文)——10 - The Future(未来)

热门文章

  1. 机器学习理论《统计学习方法》学习笔记:第二章 感知机
  2. asp多表查询并显示_零公式实现多表数据查找!3步设置,简单高效!3分钟学会,真香...
  3. Windows——系统盘隐藏分区功能
  4. Linux——主流发行版本
  5. linux 后端存储,配置NFS网络存储作为cinder的后端存储
  6. 【练习】不同排序算法执行时间比较
  7. mysql5.6 error
  8. Spring-学习笔记06【Spring的新注解】
  9. Java-Map从入门到性能分析3【LinkedHashMap(性能耗时对比、模拟LRU缓存)、TreeMap(排序、性能对比)】
  10. 必须掌握的Cookie知识点在这里