一:单链表——③查询倒数第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
请按任意键继续. . .

猜你喜欢

转载自blog.csdn.net/genzld/article/details/81155088