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;
}
c语言pop逆置单链表,C语言实现单链表相关推荐
- C语言实验——逆置正整数 Time Limit: 1000 ms Memory Limit: 65536 KiB 1189
C语言实验--逆置正整数 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 输入一个三位正整数,将它反向输出. Input ...
- java实现单链表就地逆置,20. 微软面试题:单链表就地逆放
题目是:链表操作,单链表就地逆置 分析: 这题只需要设置三个指针就搞定了,ListNode* p 表示当前指针, ListNode* fp: 上一个节点指针, ListNode * ep :下一个节点 ...
- C++ 头插法建立单链表,单链表原地逆置以及尾插法建立单链表
#include <iostream> #include <stdlib.h> #include <cstdio> typedef int ElemType; us ...
- 逆置单链表c语言程序,逆置单链表C语言
/*10.2-7-2011-05-08-19.40.c -- 第十章第二节第七题*/ #include #include /*明显常量定义*/ #define FALSE (0) #define TR ...
- c语言内容逆置程序设计,C语言程序设计练习题含程序及参考答案.docx
C语言练习题 (所提供的源程序均采用自定义函数方式解决,如不采 用函数方式,也可直接在main函数中借鉴该思想编程, 因时间有限,所有程序未能一一-验证,仅供参考使用) 1定义一个函数intfun(i ...
- C语言数组fun函数逆置数组元素,C语言
第一套 1. 程序填空 程序通过定义学生结构体数组,存储了若干个学生的学号.姓名和三门课的成绩.函数fun的功能是将存放学生数据的结构体数组,按照姓名的字典序(从小到大排序).请在程序的下划线处填入正 ...
- c语言字符串逆置,字符串逆置
满意答案 9n7j5j3m4o 2013.12.03 采纳率:49% 等级:11 已帮助:15198人 47911 zxl0714 1358 Accepted 164K 15MS G++ 0.4 ...
- c语言如何输出0,怎么用c语言打印逆置整数,零不输出?
MinRam 只是大概思路,代码并未作测试.存储后输出:按照整数来处理:int num,temp; scanf("%d",&num); if(num<0){ ...
- c语言io口置1,AVR C语言编程的小技巧-IO口置位
avr AVR C语言编程的小技巧-IO口置位 给单片机IO口置位是编程用的比较多的操作,这是我在学习C语言编程中的一点小小心得,希望大家觉得有用! AVR 单片机的IO口是标准的双向端口,首先要设置 ...
最新文章
- Axis-Parallel Rectangle
- 使用VMware VSphere WebService SDK进行开发 (四)——获取集群(Cluster, ComputeResource)的相关信息
- pandas loc 正则匹配字符串_一场pandas与SQL的巅峰大战(二)
- 开源.Net Standard版华为物联网北向接口SDK
- 十天学Linux内核之第七天---电源开和关时都发生了什么
- Android applicationId与包名的区别
- 重做系统,出现invalid switch noid
- Qt中的串口编程之一
- python之小坑:IndentationError: expected an indented block
- win10虚拟机连接不上内网服务器,win10系统虚拟机无法连接网络的解决方法
- 小米怎么快速回到顶部_打开小米这3个设置,手机越用越好用啦!你现在还不知道吗?...
- 计算机强制关机后重启报错,电脑开起来就自动关机
- idea 集成Git 遇到的问题 与解决
- RSD 教程 —— §2.2 第1次运行的配置
- 2010考研数学二第(11)题——高阶导数
- App开发智能车载应用之概述篇
- 记录一下tomcat的./startup.sh完成之后没有tomcat进程问题
- 无线ap死机无法联接服务器,无法连接无线接入点 这几步帮你轻松解决无线连接问题...
- CLA not signed yet
- 二十一世纪大学英语读写基础教程学习笔记(原文)——10 - The Future(未来)
热门文章
- 机器学习理论《统计学习方法》学习笔记:第二章 感知机
- asp多表查询并显示_零公式实现多表数据查找!3步设置,简单高效!3分钟学会,真香...
- Windows——系统盘隐藏分区功能
- Linux——主流发行版本
- linux 后端存储,配置NFS网络存储作为cinder的后端存储
- 【练习】不同排序算法执行时间比较
- mysql5.6 error
- Spring-学习笔记06【Spring的新注解】
- Java-Map从入门到性能分析3【LinkedHashMap(性能耗时对比、模拟LRU缓存)、TreeMap(排序、性能对比)】
- 必须掌握的Cookie知识点在这里