单链表的基本操作C语言实现

          单链表主要有以下基本操作:头插,尾插,头删,尾删,返回结点在链表中的位置,任意位置插入值为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;
}


     然后就可以在函数模块调用以上单链表的基本操作。这里就不再放主函数了^_^

 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值