链表面试题逆序打印,删除无头非尾节点,非头位置插入,约瑟夫环,查找中间和倒数第k个节点

这篇博客主要介绍了链表的一些常见操作,包括如何逆序打印链表、删除非头非尾节点、在非头位置插入元素,以及实现约瑟夫环问题。此外,还讲解了如何找到链表的中间和倒数第k个节点。这些内容对于理解和操作链表具有重要意义。
摘要由CSDN通过智能技术生成

头文件:

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int DataType;

typedef struct Node
{
    DataType data;
	struct Node *next;
}*PNode,Node;

void Init_LinkList(PNode *pHead);//初始化
PNode BuyNode(DataType data);//创建新节点
void PushBack(PNode *pHead,DataType data);//尾插
void Print_LinkList(PNode pHead);//打印
PNode Find(PNode pHead,DataType data);//查找值为data的节点位置

PNode EndNode(PNode *pHead);//返回最后一个节点
void ReversePrint(PNode pHead);//逆序打印链表
void DeleteNotTail(PNode pos);//删除无头非尾节点
void InsertNotHead(PNode *pHead,PNode pos,DataType data);//在链表的非头位置插入节点
PNode JosephCircle(PNode *pHead,int m);//约瑟夫环
PNode FindMidNode(PNode pHead);//查找一个单链表的中间节点
PNode FindLastKNode(PNode pHead,int k);//查找链表的倒数第k个节点
void Destroy(PNode* pHead);// 销毁链表

测试代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include"linklist.h"

//void test1()
//{
//	PNode pHead = NULL;
//    PNode pNode = NULL;
//	Init_LinkList(&pNode);
//	PushBack(&pNode,1);
//	PushBack(&pNode,2);
//	PushBack(&pNode,3);
//	/*PushBack(&pNode,4);
//	PushBack(&pNode,5);*/
//	Print_LinkList(pNode);
//	ReversePrint(pNode);
//	//DeleteNotTail(Find(pNode,3));
//	Print_LinkList(pNode);
//	InsertNotHead(&pNode,Find(pNode,4),5);
//	Print_LinkList(pNode);
//	pHead = JosephCircle(&pNode,3);
//	pHead->next = NULL;
//	Print_LinkList(pHead);
//	Destroy(&pHead);
//}
//void test2()
//{
//    PNode pNode = NULL;
//	PNode pRet = NULL;
//	Init_LinkList(&pNode);
//	PushBack(&pNode,1);
//	PushBack(&pNode,2);
//	PushBack(&pNode,3);
//	PushBack(&pNode,4);
//	//PushBack(&pNode,5);
//	Print_LinkList(pNode);
//	pRet = FindMidNode(pNode);
//	printf("pNode的中间节点为:%d\n",pRet->data);
//	Destroy(&pNode);
//}
void test3()
{
    PNode pNode = NULL;
	PNode pRet = NULL;
	Init_LinkList(&pNode);
	PushBack(&pNode,1);
	PushBack(&pNode,2);
	PushBack(&pNode,3);
	PushBack(&pNode,4);
	PushBack(&pNode,5);
	Print_LinkList(pNode);
	pRet = FindLastKNode(pNode,2);
	printf("pNode的倒数第k个节点为:%d\n",pRet->data);
	Destroy(&pNode);
}
int main()
{
	//test1();
	//test2();
	test3();
    system("pause");
	return 0;
}


函数实现:

<pre name="code" class="cpp">#include"linklist.h"

void Init_LinkList(PNode *pHead)
{
    assert(pHead);
	*pHead = NULL;
}
PNode BuyNode(DataType data)
{
	PNode newNode = NULL;
	newNode = (PNode)malloc(sizeof(Node));
	if(NULL == newNode)
	{
	    printf("out of memory.\n");
		exit(1);
	}
	else
	{
		newNode->data = data;
		newNode->next = NULL;
	}
	return newNode;
}
void PushBack(PNode *pHead,DataType data)
{
    assert(pHead);
	if(NULL == *pHead)//链表无节点
	{
		*pHead = BuyNode(data);
	}
	else//有多个节点
	{
		PNode CurNode = *pHead;
		while(CurNode->next)
		{
			CurNode = CurNode->next;
		}
		CurNode->next = BuyNode(data);
	}
}
PNode Find(PNode pHead,DataType data)
{
	PNode CurNode = pHead;
    assert(pHead);
	while(CurNode)
	{
		if(CurNode->data == data)
			break;
		else
		CurNode = CurNode->next;
	}
	return CurNode;
}
void Print_LinkList(PNode pHead)
{
	PNode CurNode = pHead;
    assert(pHead);
	while(CurNode)
	{
		printf("%d->",CurNode->data);
		CurNode = CurNode->next;
	}
	printf("over\n");
}

PNode EndNode(PNode *pHead)//返回最后一个节点
{
	PNode CurNode = *pHead;
    assert(pHead);
	while(CurNode->next)
	{
		CurNode = CurNode->next;
	}
	return CurNode;
}
void ReversePrint(PNode pHead)//逆序打印链表
{
	PNode CurNode = pHead;
    if(NULL == pHead)
		return;
	else
	{
		if(CurNode)
		{
			ReversePrint(CurNode->next);
			printf("%d ",CurNode->data);
		}
		printf("\n");
	}
}
void DeleteNotTail(PNode pos)//删除无头非尾节点
{
    if(NULL == pos || NULL == pos->next)
		return;
	else
	{
		PNode DelNode = pos->next;
		pos->data = DelNode->data;
		pos->next = DelNode->next;
		free(DelNode);
	}
}
void InsertNotHead(PNode *pHead,PNode pos,DataType data)//在链表的非头位置插入节点
{
	assert(pHead);
	if((NULL == pos) || NULL == (*pHead) || pos == *pHead)
		return;
	else//在pos之后插入
	{
		PNode newNode = BuyNode(data);
		newNode->next = pos->next;
		pos->next = newNode;
	}
}
PNode JosephCircle(PNode *pHead,int m)//约瑟夫环
{
	int count = m;
    PNode CurNode = NULL;
	PNode PreNode = NULL;
	assert(pHead);
	if(NULL == *pHead)
		return NULL;
	else
	{
	    CurNode = EndNode(pHead);//将CurNode赋值为最后一个节点
		CurNode->next = *pHead;//构成环
		CurNode = *pHead;
		while(CurNode->next != CurNode)
		{
			count = m;
			while(--count)
			{
				PreNode = CurNode;
				CurNode = CurNode->next;
			}
			PreNode->next = CurNode->next;
			free(CurNode);
			CurNode = PreNode->next;
		}
		return CurNode;
	}
}
PNode FindMidNode(PNode pHead)//查找一个单链表的中间节点
{
    PNode pFast = pHead;
	PNode pSlow = pHead;
	//while(pFast && pFast->next)//如果元素个数为偶数,则返回后面的中间值
	//{
	//	pFast = pFast->next->next;
	//	pSlow = pSlow->next;
	//}
	while(pFast->next && pFast->next->next)//如果元素个数为偶数,则返回前面的中间值
	{
		pFast = pFast->next->next;
		pSlow = pSlow->next;
	}
	return pSlow;
}
PNode FindLastKNode(PNode pHead,int k)//查找链表的倒数第k个节点
{
    PNode pFast = pHead;
	PNode pSlow = pHead;
	if(NULL == pHead)
		return;
	else
	{
		while(--k)
		{
			pFast = pFast->next;
		}
		while(pFast->next)
		{
			pFast = pFast->next;
			pSlow = pSlow->next;
		}
		return pSlow;
	}
}
void Destroy(PNode* pHead)// 销毁链表
{
	PNode CurNode = *pHead;
    assert(pHead);
	while(CurNode)
	{
	    PNode DelNode = CurNode;
		CurNode = CurNode->next;
		free(DelNode);
		DelNode = NULL;
	}
	*pHead = NULL;
}



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值