单链表的面试题:

1删除一个无头单链表的非尾节点

2在无头单链表的一个非头节点前插入一个节点

3查找单链表的中间节点,要求只能遍历一次链表

4查找单链表的倒数第k个节点,要求只能遍历一次链表

5从尾到头打印单链表

6逆置 / 反转单链表


存储结构:

typedef int DataType;

typedef struct SListNode

{

DataType _data;

struct SListNode*  _next;

}SListNode;

单链表的 增 删 查 在此省略


//替换法  pos  ——  pos->_next   //快慢指针 fast slow   //递归  

  1. 删除一个无头单链表的非尾节点

    1 --》 2 --》 3 --》 4 --》 5--》 NULL

               pos   del   next

void DelNoTailNode(SListNode* pos)  //替换法  {	assert(pos);	assert(pos->_next);	SListNode* del = pos->_next ;	SListNode* next = del->_next;	pos->_data = del->_data;	pos->_next = del->_next;    free(del);}

2.在无头单链表的一个非头节点前插入一个节点

   1 --》 2 --》 3 --》 5--》 NULL

                pos     next

                  tmp 4

1)void InsertFrontNode(SListNode* pos,DataType x)  {	assert(pos);	SListNode* tmp = _BuyNode(x);	tmp->_next = pos->_next;	pos->_next = tmp;	DataType tmpData = pos->_data;	pos->_data =tmp->_data;	tmp->_data = tmpData;  }  2)void InsertFrontNode(SListNode* pos,DataType x)    {	assert(pos);		SListNode* tmp = _BuyNode(pos->_data);  	tmp->_next = pos->_next;	pos->_next = tmp;	pos->_data = x; }

3.查找单链表的中间节点,要求只能遍历一次链表

  fast一次走两步,slow一次走一步,直至fast至NULL

SListNode* FindMidNode(SListNode* pHead)  //快慢指针{	SListNode* fast = pHead;	SListNode* slow = pHead;	while (fast&&fast->_next)	{		fast = fast->_next->_next;		slow = slow->_next;	}	return slow;}//进一步思考//struct Ret{  SListNode* first;SListNode* second; };//奇数返回一个,偶数返回两个

4.查找单链表的倒数第k个节点,要求只能遍历一次链表

 fast走k步,slow再走,至fast==NULL

SListNode* FindKNode(SListNode* pHead, DataType K)  //快慢指针{	SListNode* fast = pHead;	SListNode* slow = pHead;	while (fast&&K--)	{	         fast = fast->_next;	}	if (K > -1)  return NULL;	//if (fast == NULL) return NULL;	while (fast)	{		fast = fast->_next;		slow = slow->_next;	}	return slow;}

5.从尾到头打印单链表

void PrintTailToHead(SListNode* pHead)   //递归{	if (pHead)	{		PrintTailToHead(pHead->_next);		printf("%d->", pHead->_data);	}}

6.逆置 / 反转单链表

     1 --》 2 --》 3 --》 4 --》 NULL

 tmp,cur

               取节点tmp  newHead

             ... --》 1 --》 NULL

SListNode* Reverse(SListNode* pHead)   //取节点头插{	SListNode* cur = pHead;	//取节点,并置NULL	SListNode* newHead = NULL;	//头插	while (cur)	{		SListNode* tmp = cur;         cur = cur->_next;		tmp->_next = newHead;				newHead = tmp;	}	return newHead;}