单链表主要有以下基本操作:头插,尾插,头删,尾删,返回结点在链表中的位置,任意位置插入值为data的结点, 删除pos位置上的结点 ,求链表中节点的个数,销毁单链表 。
代码如下所示:
List.h
#ifndef __LINKED_LIST__
#define __LINKED_LIST__
typedef int DataType;
typedef struct Node
{
DataType _data;
struct Node * _pNext;
}*pNode;
void InitList(pNode* pHead);//初始化
void PushBack(pNode* pHead,DataType _data);//尾插数据
pNode BuyNode(DataType data);//构建新节点
void PopBack(pNode* pHead);//尾删
void PrintList(pNode pHead);//打印链表
void PoshFront(pNode* pHead,DataType data);//头插数据
void PopFront(pNode* pHead);//头删
void DestoryList(pNode* pHead);//销毁链表
pNode Insert(pNode pos,DataType data);//定向插入
pNode FindList(pNode pHead,DataType data);//查找
void Erase(pNode* pHead,pNode pos);//定向删除
int SizeList(pNode pHead);//节点个数
// 逆向打印单链表
void PrintListFromTail2Head(pNode pHead);
// 逆向销毁单链表
void DestroyListFromTail2Head(pNode* pHead);
// 删除单链表的非尾结点
void DeleteNotTailNode(pNode pos);
// 非头结点前插入data
void InsertNotHead(pNode pos,DataType data);
// 单链表实现约瑟夫环
pNode JosephCircle(pNode pHead, int M);
// 单链表的逆置--前后指针
pNode ReverseList_1(pNode pHead);
// 单链表的逆置--头插法
pNode ReverseList_2(pNode pHead);
//使用递归实现单链表的逆置
pNode ReverseList_3(pNode pCur,pNode pHead);
//利用栈实现逆向打印链表
void PrintListFromTail2Head_Stack(pNode pHead);
// 查找链表的中间结点---要求不能遍历单链表
pNode FindMidNode(pNode pHead);
//使用冒泡对单链表进行排序
void BubbleSort(pNode pHead);
//合并两个已序链表,合并之后新链表仍然有序
pNode MergeList(pNode pHead1,pNode pHead2);
//查找无头单链表的倒数第K个节点
pNode FindLastKNode(pNode pHead,int K);
//删除无头单链表的倒数第K个节点
pNode DeleteLastKNode(pNode* pHead,int K);
//返回链表的最后一个节点
pNode BackList(pNode pHead);
// 判断链表是否带环,如果带环求环的长度,并给出入口点
pNode HasCircle(pNode pHead);
int GetCircleLen(pNode pHead);
pNode GetEnterNode(pNode pHead,pNode pMeetNode);
//判断两个链表是否相交(不含环)
int IsCrossWithoutCircle(pNode pHead1,pNode pHead2);
//两个链表相交的交点(不含环)
pNode GetCrossWithoutCircle(pNode pHead1,pNode pHead2);
//判断两个链表是否相交(可能含环)
int IsCrossWithCircle(pNode pHead1,pNode pHead2);
//两个链表相交的交点(可能含环)
pNode GetCrossWithCircle(pNode pHead1,pNode pHead2);
#endif //__LINKED_LIST__
List.cpp
#include"LinkedList.h"
#include<stdio.h>
#include<assert.h>
#include<malloc.h>
#include<iostream>
#include<stack>
using namespace std;
void InitList(pNode* pHead)
{
assert(pHead);
*pHead = NULL;
}
pNode BuyNode(DataType data)
{
pNode pNewNode = (pNode)malloc(sizeof(struct Node));
if(NULL == pNewNode)
{
assert(0);
return NULL;
}
pNewNode->_data = data;
pNewNode->_pNext = NULL;
return pNewNode;
}
void PushBack(pNode* pHead,DataType _data)
{
assert(pHead);
if(NULL == *pHead)
{
*pHead = BuyNode(_data);
}
else
{
pNode pTailNode = *pHead;
while(pTailNode->_pNext)
{
pTailNode = pTailNode->_pNext;
}
pTailNode->_pNext = BuyNode(_data);
}
}
void PopBack(pNode* pHead)
{
if(NULL == *pHead)
return;
else if(NULL == (*pHead)->_pNext)
{
free(*pHead);
*pHead = NULL;
}
else
{
pNode pTailNode = *pHead;
pNode pPre = NULL;
while(pTailNode->_pNext)
{
pPre = pTailNode;
pTailNode = pTailNode->_pNext;
}
pPre->_pNext = NULL;
free(pTailNode);
}
}
void PrintList(pNode pHead)
{
pNode pCur = pHead;
while(pCur)
{
printf("%d--->",pCur->_data);
pCur = pCur->_pNext;
}
printf("NULL\n");
}
void PoshFront(pNode* pHead,DataType data)
{
pNode pNewNode;
assert(pHead);
pNewNode = BuyNode(data);
if(NULL == pNewNode)
return;
pNewNode->_pNext = *pHead;
*pHead = pNewNode;
}
void PopFront(pNode* pHead)
{
pNode pCur = *pHead;
assert(pHead);
if(NULL == pCur)
return;
else
{
*pHead = (*pHead)->_pNext;
free(pCur);
}
}
pNode FindList(pNode pHead,DataType data)
{
pNode pCur = pHead;
while(pCur)
{
if(pCur->_data == data)
return pCur;
else
pCur = pCur->_pNext;
}
return NULL;
}
pNode Insert(pNode pos,DataType data)
{
pNode pNewNode;
if(NULL == pos)
return NULL;
pNewNode = BuyNode(data);
if(NULL == pNewNode)
return NULL;
pNewNode->_pNext = pos->_pNext;
pos->_pNext = pNewNode;
}
void Erase(pNode* pHead,pNode pos)
{
assert(pHead);
if(NULL == *pHead || NULL == pos)
return;
if(*pHead == pos)
PopFront(pHead);
else
{
pNode pCur = *pHead;
while(pCur)
{
if(pCur->_pNext == pos)
break;
pCur = pCur->_pNext;
}
pCur->_pNext = pos->_pNext;
free(pos);
}
}
void DestoryList(pNode* pHead)
{
//正向销毁
pNode pCur = *pHead;
pNode pNext = NULL;
while(pCur)
{
pNext = pCur->_pNext;
free(pCur);
pCur = pNext;
}
*pHead = NULL;
}
int SizeList(pNode pHead)
{
int count = 1;
pNode pCur = pHead;
while(pCur)
{
count++;
pCur = pCur->_pNext;
}
return count;
}
//返回链表的最后一个节点
pNode BackList(pNode pHead)
{
pNode pCur = pHead;
if(NULL == pHead)
return NULL;
while(pCur->_pNext)
pCur = pCur->_pNext;
return pCur;
}
// 逆向打印单链表 --递归实现
void PrintListFromTail2Head(pNode pHead)
{
if (pHead != NULL){
if (pHead->_pNext != NULL){
PrintListFromTail2Head(pHead->_pNext);
}
printf("%d\t", pHead->_data);
}
}
//利用栈实现逆向打印链表
void PrintListFromTail2Head_Stack(pNode pHead){
stack<pNode> nodes;
pNode pCur = pHead;
while (pCur != NULL){
nodes.push(pCur);
pCur = pCur->_pNext;
}
while (!nodes.empty()){
pCur = nodes.top();
printf("%d\t", pCur->_data);
nodes.pop();
}
}
// 逆向销毁单链表
void DestroyListFromTail2Head(pNode* pHead)
{
assert(pHead);
if(pHead)
{
DestroyListFromTail2Head(&(*pHead)->_pNext);
free(*pHead);
*pHead = NULL;
}
}
// 删除单链表的非尾结点
void DeleteNotTailNode(pNode pos)
{
pNode pCur = NULL;
if(pos)
{
pCur = pos->_pNext;
pos->_data = pCur->_data;
pos->_pNext = pCur->_pNext;
free(pCur);
}
}
// 非头结点前插入data
void InsertNotHead(pNode pos,DataType data)
{
pNode pNewNode;
pNode pCur;
if(NULL == pos)
return;
pNewNode = BuyNode(data);
if(NULL == pNewNode)
return;
pCur = pos;
pNewNode->_pNext = pCur->_pNext;
pCur->_pNext = pNewNode;
}
// 单链表实现约瑟夫环
pNode JosephCircle(pNode pHead, int M)
{
pNode pCur;
pNode pDel;
int count = 0;
if(NULL == pHead)
return NULL;
pCur = pHead;
//构环
while(pCur->_pNext)
{
pCur=pCur->_pNext;
}
pCur->_pNext = pHead;
pCur = pHead;
while(pCur != pCur->_pNext)
{
//报数
count = M;
while(--count)
{
pCur = pCur->_pNext;
}
//删节点
pDel = pCur->_pNext;
pCur->_data = pDel->_data;
pCur->_pNext = pDel->_pNext;
free(pDel);
}
//解环
pCur->_pNext = NULL;
return pCur;
}
// 单链表的逆置--前后指针
pNode ReverseList_1(pNode pHead)
{
pNode pPre;
pNode pCur;
pNode pNext;
if(NULL == pHead || NULL == pHead->_pNext)
return NULL;
pPre = pHead;
pCur = pPre->_pNext;
pNext = pCur->_pNext;
pHead->_pNext = NULL;
while(pNext)
{
pCur->_pNext = pPre;
pPre = pCur;
pCur = pNext;
pNext = pCur->_pNext;
}
pCur->_pNext= pPre;
return pCur;
}
// 单链表的逆置--头插法
pNode ReverseList_2(pNode pHead)
{
pNode pPre = NULL;
pNode pCur = NULL;
pNode pNewHead = NULL;
if(NULL == pHead)
return NULL;
pPre = pHead;
pCur = pHead->_pNext;
while(pCur)
{
pPre->_pNext = pNewHead;
pNewHead = pPre;
pPre = pCur;
pCur = pPre->_pNext;
}
pPre->_pNext = pNewHead;
pNewHead = pPre;
return pNewHead;
}
//使用递归实现单链表的逆置
pNode ReverseList_3(pNode pCur,pNode pHead)
{
if((NULL == pCur) || (NULL == pCur->_pNext))
{
pHead = pCur;
return pCur;
}
else
{
pNode pNext = ReverseList_3(pCur->_pNext,pHead);
pNext->_pNext = pCur;
pCur->_pNext = NULL;
return pCur;
}
}
pNode FindMidNode(pNode pHead)
{
pNode pSlow = pHead;
pNode pFast = pHead;
if(NULL == pHead)
return NULL;
while(pFast && pFast->_pNext)
{
pSlow = pSlow->_pNext;
pFast = pFast->_pNext->_pNext;
}
return pSlow;
}
//使用冒泡对单链表进行排序
void BubbleSort(pNode pHead){
pNode pCur = pHead;
pNode pPreCur = NULL;
pNode pTail = NULL;
int ischange = 0;
if(NULL == pHead || NULL == pHead->_pNext)
return;
while(pTail != pHead){
pPreCur = pHead;
pCur = pHead->_pNext;
ischange = 0;
while(pCur != pTail){
if(pPreCur->_data > pCur->_data){
DataType temp = 0;
temp = pPreCur->_data;
pPreCur->_data = pCur->_data;
pCur->_data = temp;
ischange = 1;
}
pPreCur = pCur;
pCur = pCur->_pNext;
}
if(!ischange)
pTail = pPreCur;
}
}
//合并两个已序链表,合并之后新链表仍然有序
pNode MergeList(pNode pHead1,pNode pHead2){
pNode pNewHead = NULL;
pNode pCur1 = pHead1;
pNode pCur2 = pHead2;
pNode pTailNode = NULL;
if(NULL == pCur1)
return pCur2;
if(NULL == pCur2)
return pCur1;
if(pCur1->_data <= pCur2->_data){
pNewHead = pCur1;
pTailNode = pCur1;
pCur1 = pCur1->_pNext;
}
else{
pNewHead = pCur2;
pTailNode = pCur2;
pCur2 = pCur2->_pNext;
}
while( pCur1 && pCur2){
if(pCur1->_data < pCur2->_data){
pTailNode->_pNext = pCur1;
pCur1 = pCur1->_pNext;
}
else{
pTailNode->_pNext = pCur2;
pCur2 = pCur2->_pNext;
}
pTailNode = pTailNode->_pNext;
}
if(pCur1)
pTailNode->_pNext = pCur1;
if(pCur2)
pTailNode->_pNext = pCur2;
return pNewHead;
}
pNode FindLastKNode(pNode pHead,int K){
pNode pFast = pHead;
pNode pSlow = pHead;
if(NULL == pHead || K<=0)
return NULL;
while(K--){
if(NULL == pFast)
return NULL;
pFast = pFast->_pNext;
}
while(pFast){
pFast = pFast->_pNext;
pSlow = pSlow->_pNext;
}
return pSlow;
}
//删除无头单链表的倒数第K个节点
pNode DeleteLastKNode(pNode* pHead,int K){
pNode pFast = *pHead;
pNode pPreSlow = NULL;
pNode pSlow = *pHead;
if(NULL == *pHead || K<=0)
return NULL;
while(K--){
if(NULL == pFast)
return NULL;
pFast = pFast->_pNext;
}
while(pFast){
pFast = pFast->_pNext;
pPreSlow = pSlow;
pSlow = pSlow->_pNext;
}
pPreSlow->_pNext = pSlow->_pNext;
return *pHead;
}
//判断链表是否带环
pNode HasCircle(pNode pHead)
{
pNode pFast = pHead;
pNode pSlow = pHead;
if(NULL == pHead)
return NULL;
while(pFast && pFast->_pNext)
{
pFast = pFast->_pNext->_pNext;
pSlow = pSlow->_pNext;
if(pSlow == pFast)
return pFast;
}
return NULL;
}
//得到带环链表环的长度
int GetCircleLen(pNode pHead)
{
pNode pMeetNode = HasCircle(pHead);
pNode pCur = pMeetNode;
int count = 1;
if(NULL == pMeetNode)
return 0;
while(pCur->_pNext != pMeetNode)
{
count++;
pCur = pCur->_pNext;
}
return count;
}
//含环链表入口点
pNode GetEnterNode(pNode pHead,pNode pMeetNode)
{
pNode pH = pHead;
pNode pM = pMeetNode;
if(NULL == pHead || NULL == pMeetNode)
return NULL;
while(pH != pM)
{
pH = pH->_pNext;
pM = pM->_pNext;
}
return pH;
}
//判断两个链表是否相交(不含环)
int IsCrossWithoutCircle(pNode pHead1,pNode pHead2)
{
pNode pTailNode1 = NULL;
pNode pTailNode2 = NULL;
if(NULL == pHead1 || NULL == pHead2)
return 0;
pTailNode1 = BackList(pHead1);
pTailNode2 = BackList(pHead2);
if(pTailNode1 == pTailNode2)
return 1;
return 0;
}
//两个链表相交的交点(不含环)
pNode GetCrossWithoutCircle(pNode pHead1,pNode pHead2)
{
int size1 = 0,size2 = 0;
int grap = 0;
pNode pCur1 = pHead1;
pNode pCur2 = pHead2;
if(!IsCrossWithoutCircle(pHead1,pHead2))
return NULL;
size1 = SizeList(pHead1);
size2 = SizeList(pHead2);
grap = size1 - size2;
if(grap>0)
{
while(grap--)
pCur1 = pCur1->_pNext;
}
else
{
while(grap++)
pCur2 = pCur2->_pNext;
}
while(pCur1 != pCur2)
{
pCur1 = pCur1->_pNext;
pCur2 = pCur2->_pNext;
}
return pCur1;
}
//判断两个链表是否相交(可能含环)
int IsCrossWithCircle(pNode pHead1,pNode pHead2)
{
pNode pMeet1 = HasCircle(pHead1);
pNode pMeet2 = HasCircle(pHead2);
if(NULL == pMeet1 && NULL == pMeet2)//都不带环
{
if(BackList(pHead1) == BackList(pHead2))
return 1;
}
else if(pMeet1 && pMeet2)//都带环
{
pNode pCur = pMeet1;
while(pCur->_pNext != pCur)
{
if(pCur == pMeet2)
return 2;
pCur = pCur->_pNext;
}
if(pCur == pMeet2)
return 2;
}
return 0;
}
然后就可以在函数模块调用以上单链表的基本操作。这里就不再放主函数了^_^