问题:
一个单链表,很长,遍历一遍很慢,我们仅知道一个指向某节点的指针pNode,而我们又想删除这个节点。
思路:
将该结点的下一个结点的内容拷贝到当前结点,然后删除下一个结点。
如果该结点时最后一个结点,则必须遍历一遍单链表,找到前面一个结点,然后删掉该结点。
注意:
虽然最后一种情况是线性复杂度的,但是总体上来看还是常数时间的。
// LinkTable.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
//链表的结构体
struct node
{
char val;
node * next;
};
//2,找第4个结点
struct node * create( string & str_link )
{
int len = str_link.length();
struct node * phead = new node(); //带有表头的链表,表头中不存储任何元素
struct node * preNode = phead;
for( int i=0; i<len; i++ )
{
struct node * pNode = new node();
pNode->val = str_link[i];
pNode->next = NULL;
preNode->next = pNode;
preNode = pNode;
}
return phead;
}
void out_link( struct node * phead )
{
if( phead == NULL )
return;
struct node * pNode = phead->next;
while( pNode )
{
cout <<pNode->val;
pNode = pNode->next;
}
cout << endl;
}
struct node * find_third_node( struct node * phead )
{
if( !phead ) return NULL;
//快指针先走4步
struct node *pFast = phead;
struct node *pSlow = phead;
int num =4;
while(num--)
{
pFast = pFast->next;
if(!pFast) //还没走完就没了
{
return NULL;
break;
}
}
//快慢指针一起走
while(pFast)
{
pFast = pFast->next;
pSlow = pSlow->next;
}
return pSlow;
}
struct node * find_last_node( struct node * phead )
{
struct node *pNode = phead;
while(pNode->next)
{
pNode = pNode->next;
}
return pNode;
}
void delete_node( struct node * phead, struct node * pNode )
{
if( !phead ) return;
//如果pNode是最后一个结点,则找到前面一个结点
if( !pNode->next )
{
struct node *preNode = phead;
while(phead)
{
if(preNode->next==pNode)
break;
else
preNode = preNode->next;
}
if( !preNode )
{
cout <<"The node is not in the link list" << endl;
return;
}
preNode->next = NULL;
delete pNode;
}
else //否则拷贝下一个元素的内容,并删除下一个结点
{
struct node * pNext = pNode->next;
pNode->val = pNext->val;
pNode->next = pNext->next;
delete pNext;
}
}
void test()
{
string str;
cin >> str;
struct node *phead = create( str );
cout << "The Link is : ";
out_link( phead );
struct node *pNode = find_third_node(phead);
delete_node( phead, pNode );
cout << "delete the last third node:" <<endl;
out_link( phead );
pNode = find_last_node(phead);
delete_node( phead, pNode );
cout << "delete last node: "<<endl;
out_link( phead );
}
int _tmain(int argc, _TCHAR* argv[])
{
test();
return 0;
}