分析:
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);
}
/*
以上代码都是原创,如有问题望大家批评改正。
*/