输入一个单向链表,输出其倒数第k个结点

分析:

1、一个单向的带头节点的链表。

2、输出其倒数第K个结点。


在这里介绍两种方法。

1、常规的做法,先遍历链表,统计链表的长度,然后通过计算,在遍历链表,找到指定的结点。(此方法等于遍历了两遍链表)

2、只遍历一遍链表,通过两个指针之间的距离来控制,遍历的同时将两个指针同向后移动,当一个指针指到末尾结点时,通过另一个指针就能找到指定结点。


方法一:

//C实现
#include <stdio.h>
#include <malloc.h>

typedef struct NODE
{
	char data;
	struct NODE *next;
}Node, *pNode;

void CreateLink(pNode *phead)
{
	int n = 0, i = 0;
	pNode p = NULL, q = NULL;

	*phead = (pNode)malloc(sizeof(Node) * 1);
	(*phead)->data = '\0';
	(*phead)->next = NULL;

	puts("Please enter the number of node");
	scanf_s("%d",&n);
	p = *phead;
	while (n--)
	{
		q = (pNode)malloc(sizeof(Node)*1);
		q->data = 'A' + i++;
		q->next = NULL;

		p->next = q;
		p = q;
	}
}

void ShowLink(pNode phead)
{
	pNode p = phead;

	while (p->next != NULL)
	{
		printf("%2c",p->next->data);
		p = p->next;
	}
	putchar(10);
}

void Statistic(pNode phead, int *n)
{//计算链表长度
	pNode p = phead;
	int count = 0;

	while (p->next != NULL)
	{
		count++;
		p = p->next;
	}
	*n = count;
}

void PointNode(pNode phead, int n)
{
	pNode p = phead;
	int k = 0;

	puts("Please enter the number of point");
	scanf_s("%d",&k);

	if (k > n || k <= 0)
		return;

	k = n - k;//计算倒数第k个结点的位置
	while (k--)//移动k次指针,找到倒数第k个结点
	{
		p = p->next;
	}
	printf("%2c\n", p->next->data);
}

void main()
{
	pNode pHead = NULL;
	int n;

	CreateLink(&pHead);
	ShowLink(pHead);

	Statistic(pHead, &n);
	
	while (1)
	{
		PointNode(pHead, n);
	}
}


方法二:(此方法借鉴与网络,我将其称为指针卡位法)

//C实现
#include <stdio.h>
#include <malloc.h>、

typedef struct NODE
{
	char ch;
	struct NODE *next;
}Node,*pNode;

void CreateLink(pNode *_pHead)
{
	int n = 0, i = 0;
	pNode p = NULL, q = NULL;

	*_pHead = (pNode)malloc(sizeof(Node)*1);
	(*_pHead)->ch = '\0';
	(*_pHead)->next = NULL;
	p = *_pHead;

	puts("Please enter the number of node");
	scanf_s("%d",&n);

	while (n--)
	{
		q = (pNode)malloc(sizeof(Node)*1);
		q->ch = 'A' + i++;
		q->next = NULL;

		p->next = q;
		p = q;
	}
}

void ShowLink(pNode _pHead)
{
	pNode pHead = _pHead;
	pNode p = pHead;

	while (p->next != NULL)
	{
		printf("%2c",p->next->ch);
		p = p->next;
	}
	putchar(10);
}

void Doit(pNode _pHead)
{
	pNode pHead = NULL;
	pNode p = NULL, q = NULL;
	int k = 0;

	if (NULL == _pHead)//若_pHead指针为空,则直接返回
		return;
	pHead = _pHead;	//头指针,以及指针p、q都指向_pHead
	p = pHead;
	q = pHead;

	puts("Please enter the numeber of point");
	scanf_s("%d",&k);
	
	while (k--)//先让指针p移动到与q指针距离为k的位置
	{
		if (p->next != NULL)//当链表足够长,则移动p指针
		{
			p = p->next;
		}
		else
		{
			if (k != 0)//当p->next == NULL 时,k != 0,则证明此链表不存在到数第k个位置
			{
				puts("This link is short");
			}
		}
	}// end of while

	while (p->next != NULL)//让p和q指针保持k距离一起向后移动
	{
		p = p->next;
		q = q->next;
	}

	//当p->next == NULL时,q实际指向倒数 k+1 个位置,让后q->next->ch输出倒数第 k 个数
	printf("This point is %c\n",q->next->ch);
}

void DeleteLink(pNode _pHead)
{
	pNode pHead = NULL;
	pNode p = NULL, q = NULL;

	if (NULL == pHead)
		return;

	pHead = _pHead;
	p = pHead;

	while (p->next != NULL)
	{
		q = p;
		p = p->next;
		free(q);
	}
	free(p);
}

void main()
{
	pNode pHead = NULL;

	CreateLink(&pHead);
	ShowLink(pHead);

	Doit(pHead);
	DeleteLink(pHead);
}



/*

以上代码都是原创,如有问题望大家批评改正。

*/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值