【华为oj2065】输出单向链表倒数第k个节点

/***************************************************
输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第0个结点为链表的尾指针。
链表结点定义如下:
struct ListNode
{
      int       m_nKey;
      ListNode* m_pNext;
};
详细描述:
接口说明
原型:		 ListNode* FindKthToTail(ListNode* pListHead, unsignedint k);
输入参数:	 ListNode* pListHead  单向链表
			 unsigned int k  倒数第k个结点
输出参数:	无
返回值:	正常返回倒数第k个结点指针,异常返回空指针

*************************************************/
#include<iostream>
#include<assert.h>
using namespace std;

/************结构体定义链表节点***********************/

struct ListNode
{
	int data;
	ListNode* next;
	
};


/**********创建单链表*************/
ListNode* createList( )
{
	ListNode* newNode,*last,*head;
	head = NULL;
	last = NULL;
	int n ;
	cin >> n;

	//将输入的值加入链表
	int num = 0;

	while(n--)
	
	{
		 cin >> num ;
		 newNode = new ListNode;//新建一个jiedian
		 assert(newNode !=NULL);
		 newNode->data = num;//数组第一个值赋给头指针
		 newNode->next = NULL;//创建了头节点
	  
		if(head == NULL)//如果时头结点
		{
			head = newNode;
			last = newNode;
		}
		 else
		{   
			last->next = newNode;//让节点的后继指向新节点
			last = newNode;//把尾指针指向最后一个
	
		}
	

	}

	
		return head;
	
}

/*******************定义两个节点查找第k个节点******************/
ListNode* NodeFind(ListNode* head,int k)
{
	ListNode *p;
	ListNode *q;
	assert(k>=0);
	p = q =head;//两个指针都赋值为头指针

	for(;k>0&&q != NULL;k--)//q先向前移k步
	{
		q = q->next;
	}

	if(k>0) return NULL;

	while(q!=NULL)//整体移动p,q,直到把q移动表尾,p所在的刚好就是倒数第k个节点
	{
		p = p->next;
		q = q->next;
	}
	return p;
}

int main()
{
	ListNode* knode = NULL;
	ListNode* mhead= NULL;
	int k=0;
	
	mhead = createList(); 
	cin >>k;
	knode = NodeFind(mhead,k+1);
	cout << knode->data <<endl;

	
	system("pause");
	return 0;


}


由于刚开始看数据结构链表那里,很多都一知半解,花了很长时间终于解出来这道题了。那就趁热打铁总结一下:

遇到的问题:

1.关于链表的构造

        刚开始不知道在哪里看的说是把数字都存入数组,然后把数组赋给链表,搞了半天没弄好,晚上请教一个oj群里的人也没请教出个所以然,但被提示了一点,可以直接赋值给链表,后来我自己看书才知道,有序的就用数组来表示,至于这种能插入能删除就用链表表示了。

       怎么存到链表里,本来想把输入放到主函数里,但是发现写的子函数,每次都要初始化head和last为NULL,这样就老是有冲突和错误,于是把输入的函数也写到了子函数里

2.关于输入字符的问题

cin不可以接受空格回车键之类的,所以完全不用考虑空格什么的,不用考虑输入一个字符串,直接用while循环,给出要输入的个数,cin>>num就可以,他会自己获取下一个数字,管你中间是不是输了一堆乱七八糟的。

3.关于原理

(1)就是设置两个指针,先让指针2向前k步,接着两个同时移动,指针2指向尾端即NULL时,则指针1刚好指向倒数第k-1个(题目中最后一个为倒数0)

(2)网上还有一种原理:从头遍历链表,输出第n-k-2个节点即可


http://blog.csdn.net/v_july_v/article/details/6447013 july的链表追赶问题



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值