算法題:求鏈表倒數第K個結點

說明:本文僅供學習交流,轉載請標明出處,歡迎轉載!

       題目:給出一個單鏈表,返回倒數第K個結點,最後一個結點爲倒數第1個

     《劍指offer》上面給的解法是設置兩個指針,這裏記爲p1、p2,先讓p2走(k-1)步,然後p1、p2同時走,當p2走到最後一個結點時,p1所指向的結點就是倒數第k個結點。

         我覺得按照這樣的邏輯寫代碼反而更容易出錯,因爲我們需要把我兩件重要的問題:(1).p2先走(k-1)步;(2)循環結束的條件是p2到達最後一個結點,即p2->next==NULL。顯然這樣不太容易控制,我的想法是先讓p2先走k步,然後p1,p2一塊走,循環結束的條件是p2到達NULL,即p2==NULL,這樣比較直觀

         我們用Node *FindLastK(Node *head,int k)表示求解函數,同時在要注意以下特殊情況:

       (1)處理空鏈表的情況,即head=NULL的情況;

       (2)處理k<1的情況;(注意k從1開始)

       (3)處理鏈表長度小於k的情況。

         代碼如下:

#include<iostream>
using namespace std;
struct Node
{
	int value;
	Node* next;
	Node(int v):value(v){}
};
/*創建一個鏈表,1->2->3->4->5->6->7*/
Node* CreateList()//創建一個單鏈表
{
   Node *head;
   Node *n1=new Node(1);
   Node *n2=new Node(2);
   Node *n3=new Node(3);
   Node *n4=new Node(4);
   Node *n5=new Node(5);
   Node *n6=new Node(6);
   Node *n7=new Node(7);
   head=n1;
   n1->next=n2;
   n2->next=n3;
   n3->next=n4;
   n4->next=n5;
   n5->next=n6;
   n6->next=n7;
   n7->next=NULL;
   return head;
}
void FreeList(Node *head)//將鏈表空間釋放
{
	if(head==NULL)
	{
		return ;
	}
	else
	{
		Node *temp=head->next;
		delete head;
		head=temp;
		FreeList(head);
	}
}
void VisitList(Node *head)//遍歷鏈表中的元素,用遞歸的方法遍歷
{
	if(head)
	{
		cout<<head->value<<"->";
		VisitList(head->next);
	}
	else
	{
		cout<<"null"<<endl;
	}
}
Node *FindLastK(Node *head,int k)//查找倒數第K個元素,最後一個元素時倒數第一個
{
	if(head==NULL || k<1)
	{
		return NULL;
	}
	else
	{
		Node *pre,*p;
		pre=p=head;
		int i;
		for(i=0;p && i<k;i++)//要保證p存在,p先走k步
		{
			p=p->next;
		}
		if(i<k)//說明沒走到k步,即k大於鏈表的長度
		{
			return NULL;
		}
		else//如果一切正常,則兩者同時走
		{
			while(p)
			{
				p=p->next;
				pre=pre->next;
			}
		}
		return pre;
	}
}
int main()
{
	Node *head=CreateList();
	cout<<"鏈表輸出爲:";
	VisitList(head);
	int k;
	while(cin>>k)
	{
		Node *temp=FindLastK(head,k);
		if(temp)
		{
			cout<<"倒數第"<<k<<"個元素爲:"<<temp->value<<endl;
		}
		else
		{
			cout<<"輸入的K超過了鏈表的長度!"<<endl;
		}
	}
	FreeList(head);//釋放鏈表空間
	return 0;
}

         測試結果如下:


參考資料------《劍指offer》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章