题目:输入一个单向链表,输出该链表中倒数第k个结点。最后一个结点为倒数第一个结点。
思路:
1.首先遍历链表的长度获得链表的length,则它的倒数第k个结点就是正数length-k+1个结点,但这需要遍历链表两次
2.使用两个指针可以实现遍历一次,first指针指向头结点,second指针指向first之后的k-1个结点,然后两个结点循环向后移动,直到second结点到达链表的最后一个结点时,first结点指向倒数第k个结点。
注意:
1.要判断传来的参数 *head和k是否合法
2.判断k是否超过链表的长度。
代码如下:
struct listnode { int data; listnode *next; }; //使用尾插法构建链表 listnode *init() { listnode *head=(listnode *)malloc(sizeof(listnode)); head->next=NULL; listnode *last=head; int data; cout<<"请输入:(按-1结束链表)"<<endl; cin>>data; while(data!=-1) { listnode *temp=(listnode *)malloc(sizeof(listnode)); temp->data=data; temp->next=last->next;//last的下一个为NULL last->next=temp; last=temp; cout<<"请输入:(按-1结束链表)"<<endl; cin>>data; } return head; } //打印链表 void print(listnode *head) { listnode *temp=head->next; while(temp!=NULL) { cout<<" "<<temp->data; temp=temp->next; } } //找到链表的第k个结点 listnode *findnumberK(listnode *head,unsigned int k) { //判断参数是否正确 if(head==NULL||k==0) { return NULL; } listnode *first=head; listnode *second=first; //第二个指针向前走k-1次 for(int i=0;i<k-1;i++) { //判断第二个指针的next是否为空 if(second->next!=NULL) second=second->next; //没有第k个结点 else return NULL; } //两个指针循环向前走,第二个指针到达链表结尾,则第一个指针到达第k个结点 while(second->next) { first=first->next; second=second->next; } return first; }
测试代码以及运行结果:
int main() { listnode *head=init(); print(head); cout<<endl; cout<<findnumberK(head,3)->data<<endl; return 0; }