第一次写博客,是一枚标准的greenhorn,诚惶诚恐,不过人生总有那许多第一次,下定决心就要努力坚持做下去。 好了废话少说,切入正题。
我们在面试找工作的时候经常会遇到各种各样的单链表相关的题目,题目本身并不难,但还是会有一些tricky的地方,现将我在复习和面试过程中遇到的关于单链表相关的问题做个总结。
首先我们来定义单链表的数据结构
struct ListNode
{
int data;
struct ListNode *next;
};
题目1:在单链表的尾部插入一个新的节点
void appendListTail(struct ListNode **pHead, struct ListNode *newTail)
{
if(pHead == NULL) return; //头指针的指针为空,我们无法进行进一步操作
if(newTail == NULL) return; //对于空的tail我们不需要append.
struct ListNode *head = *pHead;
if(head == NULL) {
*pHead = newTail; // 当原链表头为空的时候,我们需要修改修改头指针。
return;
}
while( head -> next != NULL){ //正常的插入操作
head = head -> next;
}
head -> next = newTail;
}
题目2:给定一个结点以及头指针从链表中删除该节点
void removeNode(struct ListNode **pHead, struct ListNode *node)
{
if(pHead == NULL) return;
if(node == NULL) return;
struct ListNode *head = *pHead;
if(head == node) {
*pHead = head -> next;
delete head;
return;
}
while(head != NULL && head->next != node)
{
head = head -> next;
}
if( head == NULL)
return;
else {
head -> next = node -> next;
delete node;
}
}
题目3:单链表取中点并返回该结点指针
struct ListNode * getMiddleNode(struct ListNode *head)
{
if(head == NULL) return NULL;
struct ListNode *fastNode = head;
struct ListNode *slowNode = head;
while(fastNode != NULL && fastNode -> next !=NULL)
{
fastNode = fastNode->next->next;
slowNode = slowNode -> next;
}
return slowNode;
}
题目4:单链表取距离尾结点N的结点
struct ListNode * getNthNodeFromTail(struct ListNode *head, int n)
{
if(head == NULL) return NULL;
struct ListNode *fastNode = head;
struct ListNode *slowNode = NULL;
int i = 0;
while( i<n && fastNode != NULL)
{
fastNode = fastNode->next;
i++;
}
if(fastNode == NULL) return slowNode;
slowNode = head;
while(fastNode->next != NULL)
{
fastNode = fastNode -> next;
slowNode = slowNode -> next;
}
return slowNode;
}
题目5:单链表反序,并返回新链表的头指针
struct ListNode *reverseList(struct ListNode *head)
{
struct ListNode *newHead = NULL;
struct ListNode *tmp = NULL;
while(head != NULL)
{
tmp = head;
head = head -> next;
tmp->next = newHead;
newHead = tmp;
}
return newHead;
}