在一个只有头指针的单向链表中查找链表中倒数第K个位置上的节点元素(1)

?思路一:通过设指针q指向链表头,指针p指向链表的第一个元素,q向后移动K个节点后,p和q相距k,因此,当q移动到链表尾端的时候,p正好在链表的倒数第K个位置

?思路二:将链表元素依次入栈,然后弹出第K个节点(利用了倒数和正数是相对的概念,也利用了栈的这种特殊的特性)

不过相比较而言,还是第一种方法算法性能好

我实现了第一种方法,重要函数是 int find_K_number(List L,int k)

int find_K_number(List L,int k)
{
	int i = 0;
	Node* p = L.head;
	Node* q = L.head;
	p = p -> next;
	while(q && i < k) //这里要加上 q && 不然的话就还是会移动,就出现段错误
	{
		q = q->next;
		i++;
	}

	if(q == NULL)
	{
		printf("find position wrong!\n");
		return 0;
	}
	while(q -> next != NULL)
	{
		q = q->next;
		p = p->next;
	}
	printf("%d\n",p->value);
	return 1;
}

程序所有代码

//查找链表倒数第k个位置
//由于链表不是顺序存储,所以其链表长度不知道(我的思维死在了这里)
//若遍历了一遍链表后求出长度后再遍历一次则太麻烦了
//通过两个指针,步长为k,来找到倒数第k个位置上的结点

#include<stdio.h>
#include<stdlib.h>

typedef struct node
{
	int value;
	struct node* next; //这里要用struct node
}Node;

typedef struct list
{
	Node * head;//表头指针

}List;

void InitList(List* L)
{
	Node* first;  //表头节点
	first = (Node*)malloc(sizeof(Node));
	if(!first)
		printf("wrong1!\n");

	Node * tail;
	L->head = first; //头指针指向头节点
	tail = L->head;

	first->next = NULL;
	first->value = 0;

	for(int i = 1;i <= 10;i++)
	{
		Node *new = (Node*)malloc(sizeof(Node));
		if(!new)
			printf("wrong2!\n");
		new -> value = i;
		tail -> next = new;
		new -> next = NULL;
		tail = new;
	}
}

//用两个指针来查找步长
int find_K_number(List L,int k)
{
	int i = 0;
	Node* p = L.head;
	Node* q = L.head;
	p = p -> next;
	while(q && i < k) //这里要加上 q && 不然的话就还是会移动,就出现段错误
	{
		q = q->next;
		i++;
	}

	if(q == NULL)
	{
		printf("find position wrong!\n");
		return 0;
	}
	while(q -> next != NULL)
	{
		q = q->next;
		p = p->next;
	}
	printf("%d\n",p->value);
	return 1;

}


void printList(List L)
{
	Node *p = L.head;
	while(p -> next != NULL)
	{
		p = p -> next;
		printf("%d ", p->value);
	}

	printf("\n");

}

int main(int argc, char const *argv[])
{
	List L;
	InitList(&L);
	//printList(L);
	int find_or_not = find_K_number(L,2);//查找倒数第二个元素

	return 0;
}

运行截图
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五月的天气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值