您的位置:首页 > 其它

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

2014-10-12 00:03 585 查看
分析:

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);
}


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

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐