1. 程式人生 > >一:單鏈表——③查詢倒數第k個節點(O(1))

一:單鏈表——③查詢倒數第k個節點(O(1))

製作人  :TheShyclear

製作時間:2018-7-21

製作內容:查詢單鏈表中的倒數第k個數據

版本號 :8.0

缺陷:頭節點只能插入一次,不能在1號節點出插入,詳細看Insert函式

注意:頭指標的不可改變性

思路:單鏈表中的許多問題需要用到兩個指標的配合,因為單鏈表只有後繼節點,無法找到後繼節點。

當我們拿到這個問題時,第一反應肯定是:用一個指標指向頭節點然後呢迴圈計數到最後節點,這樣我們就知道了連結串列的總長度le,然後那麼倒數第k個節點就是第le+1-k個節點,這樣的話時間複雜度就是O(n)

那麼我們是否有一種更簡便的迅捷的方法呢?使其複雜度為O(1)

呢?當然可以!由於單鏈表的特殊性,只能表示後繼節點,而無法表示前驅節點,通常情況下,我們都會採取輔助指標的方法來解決相應的問題。

具體程式碼實現:

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

typedef int Elemtype;

typedef struct ListNode
{
	Elemtype data;//值域
	ListNode *m_pNext;//指標域
}ListNode,*PListNode;

ListNode* BuyNode()
{
	ListNode* p = (ListNode*)malloc(sizeof(ListNode));
	if(NULL == p)
	{
		printf("buynode is error:\n");
		exit(1);
	}
	memset(p,0,sizeof(ListNode));
	return p;
}

void InitList(PListNode &p)
{
	p = BuyNode();
	p->m_pNext = NULL;
	p->data = 0;
}
int GetLength(PListNode &head)//問題出現:不能直接操作head節點
{
	int count = 0;
	PListNode s = head;
	while(s!=NULL)
	{
		count+=1;
		s=s->m_pNext;
	}
	return count;
}
void InsertList(PListNode &p,Elemtype x,int pos)
{
	if(pos<1 || pos>GetLength(p)+1)
	{
		printf("input pos is error:\n");
		exit(1);
	}
	PListNode s = p;//頭節點 s
	if(pos == 1)
	{
		p->data = x;
		p->m_pNext = NULL;
	}
	else
	{
		while(pos-2)
	    {
			s = s->m_pNext;
		    --pos;
	     }//s指向前驅
	     PListNode r =s->m_pNext;

	     PListNode q = BuyNode();
	     q->data = x;

	     s->m_pNext = q;
	     q->m_pNext = r;
	}
}

PListNode Find_Kth_To_Tail(PListNode &p,int k)
{
	if(k<1 || k>GetLength(p))
	{
		printf("input k is error:\n");
		exit(1);
	}
		
	PListNode s =p;
	PListNode q =p;


	for(int i=0;i<k-1;++i)
	{
		s = s->m_pNext;
	}
	while(s->m_pNext != NULL)
	{
		s = s->m_pNext;
		q = q->m_pNext;
	}

	return q;
}
void Show_List(PListNode &head)
{
	PListNode s =head;
	while(s != NULL)
	{
		printf("%d ",s->data);
		s = s->m_pNext;
	}
}
void main()
{
	PListNode head;
	InitList(head);
	for(int i=1;i<5;++i)
	{
		InsertList(head,i+10,i);
	}
	Show_List(head);
	PListNode r = Find_Kth_To_Tail(head,2);
	printf(" ");
	printf("%d \n",r->data);

}

執行結果:

11 12 13 14  13
請按任意鍵繼續. . .