您的位置:首页 > 其它

13--输出链表中倒数第k个节点,

2015-09-27 19:03 375 查看
//
//  main.cpp
//  test_list_oper
//
//  Created by Hugo Cao  on 15/7/6.
//  Copyright (c) 2015年 Hugo Cao . All rights reserved.
//

/*
题目:
输出链表中倒数第k个节点,
输入一个链表,输出链表中倒数第K个节点,为了符合大多数人的习惯,本题从1开始计数,
即链表的尾节点是倒数第一个是1节点,例如输入一个6个节点,
从头节点开始,依次是1,2,3,4,5,6。倒数第三个节点是4.

解题思路:
(1) 最简单的方式,遍历一遍,然后计算倒数第k个位 n-k+1
(2) 第二种方式,只遍历一次,用空间代替时间,设置第二个指针,让一个指针先出发,
由于输出倒数第K个,所以,输出位置是n - k + 1.所以当前一个节点,走了K-1时,第二个出发。

引申:这个问题,提示了一个很好的解决问题的方式,也是空间换时间很好的例证。
(1)比如打印单链表中间的那个元素,依旧可以设置2个指针,让一个快一个慢,一个一次走1步,另一个走2步。
(2)判断一个链表是否是循环链表,依旧可以设置一个快指针,一个慢指针,判断是否能追上另一个,如果可以追上,就是循环列表。
*/

#include <stdio.h>
#include <stdlib.h>
#include <stack>
#include <iostream>
using namespace std;

typedef struct ListNode
{
int m_nValue;
struct ListNode *m_pNext;
} lNode;

//添加元素结点
void listAddNode(lNode *head)
{
lNode *p = head, *p_Inter = NULL;

if (!(p_Inter = ((lNode *)malloc(sizeof(lNode)))))
{
printf("the memery is don't create it\n");
return;
}
p_Inter->m_pNext = NULL;

int data;
printf("请输入数字:\n");
scanf("%d", &data);
p_Inter->m_nValue = data;

while (p->m_pNext != NULL)
{
p = p->m_pNext;
}

p->m_pNext = p_Inter;

}

//创建元素结点
lNode* createList(lNode *head)
{
if (!(head = ((lNode *)malloc(sizeof(lNode)))))
{
printf("the memery is don't create it\n");
return NULL;
}
head->m_pNext = NULL;
int data;
printf("请输入数字:\n");
scanf("%d", &data);
head->m_nValue = data;

lNode *p = head;
char X_cin = 'Y';
while (true)
{
printf("是否继续添加:N/n \n");
cin >> X_cin;

if (X_cin == 'y' || X_cin == 'Y')
{
;
}
else if (X_cin == 'N' || X_cin == 'n')
{
return head;
}
else
{
;
}

listAddNode(p);
}

}

//显示列表
void showList(lNode *head)
{
if (NULL == head)
{
cout << "list is empty \n" << endl;
return;
}

lNode *p = head;

while (p != NULL)
{
printf("%d\n", p->m_nValue);
p = p->m_pNext;
}

}

//翻转链表
void reversePut(lNode *point)
{
stack <int> stack_rev;
lNode *p = point;

while (p != NULL)
{
stack_rev.push(p->m_nValue);
p = p->m_pNext;
}

cout << "翻转以后的输出" << endl;
while (!stack_rev.empty())
{
cout << stack_rev.top() << endl;
stack_rev.pop();
}
}

//输出倒数第K个元素节点,遍历所有节点型。
void firstPrintNode(lNode *head, int kNum)
{
if (head == NULL || kNum <= 0)
return;

int length = 0;
lNode *p = head;

while (p != NULL) {
p = p->m_pNext;
length++;
}
if (length < kNum)
{
cout << "链表长度为:" << length << ", 而遍历的节点位置是: "<< kNum << endl;
return;
}
cout << "链表长度为:" << length;
p = head;
while (length != kNum) {
length--;
p =  p->m_pNext;
}

cout << "  输出倒数第K个元素节点: " << p->m_nValue << endl;
}

//输出第K个结点,第二种方式,两个指针
void secondPrintNode(lNode *head, int kNum)
{
if (head == NULL || kNum <= 0)
return;

lNode *p1 = head;
lNode *p2 = head;
int length = kNum;

while (p1 != NULL) {
p1 = p1->m_pNext;
length--;
if (length < 0)
p2 = p2->m_pNext;
}

cout << "  输出倒数第K个元素节点: " << p2->m_nValue << endl;
}

int main()
{
lNode *head = NULL;

head = createList(head);
showList(head);
//翻转链表
//reversePut(head);

secondPrintNode(head, 3);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: