要删除链表倒数第k个结点,需满足下述条件:
1、链表不能为空;
2、k不能等于0;
3、k不能大于链表的结点总数(链表长度)
删除时,应先找到倒数第k个结点,并标记该结点的前一个结点和后一个结点。
找倒数第k个结点:
1、aNode指向头结点phead,aNode在链表上走k-1步
2、bNode指向头结点phead
3、两个指针一起沿着链表走
4、aNode指向链表的尾结点时,bNode指向倒数第k个结点。
如图,k=3:
参考代码:
找倒数第k个结点:
ListNode* List::Findkthtotail(ListNode** head, int k)
{
if (NULL == *head || k==0)
return NULL;
ListNode* aNode = *head;
ListNode* bNode = NULL;
for (int i = 0; i < k-1; i++)
{
if (aNode->_next != NULL)
{
aNode = aNode->_next;
}
else
return NULL;
}
bNode = *head;
while (aNode->_next != NULL)
{
aNode = aNode->_next;
bNode = bNode->_next;
}
return bNode;
}
删除倒数第k个结点:
bool List:: Delkthtotail(ListNode** head, int k)
{
if (NULL == *head || k == 0)
return false;
//倒数第K个结点的前一个节点
ListNode* preNode = *head;
for (int i = 0; i < k - 1; i++)
{
if (preNode->_next != NULL)
preNode = preNode->_next;
else
return false;
}
//倒数第K个结点
ListNode* Node = Findkthtotail(head, k);
//倒数第K个结点的后一个节点
ListNode* NextNode = Node->_next;
preNode->_next = NextNode;
delete Node;
Node->_next = NULL;
}
struct Node
{
int _data;
Node* _next;
Node(int data)
:_data(data)
{}
};
//逆置单链表(三指针法)
Node* reverse(Node* head)
{
Node* pre = NULL;
Node* node = head;
Node* reverseNode = NULL;
while (node!=NULL)
{
Node* next = node->_next;
if (next == NULL)
{
reverseNode = node;
}
node->_next = pre;
pre = node;
node = next;
}
return reverseNode;
//test code
void Print(Node* head)
{
Node* node = head;
while (node != NULL)
{
cout << node->_data << "->";
node= node->_next;
}
cout << "\n";
}
void test()
{
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;
Node* phead = reverse(head);
Print(phead);
}