?思路一
:通过设指针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;
}
运行截图