题目:给定单向链表的头指针和某结点指针,实现函数在O(1)时间内删除指定节点。
思路:由于没有要删除结点(j结点)的前一个结点(i结点)指针,通常想法是从头开始遍历找到指定结点的前一个结点(i结点),然后使i结点的指针指向j结点的后一个结点k结点。但是这样是O(n)的时间复杂度,不符合要求。
解决方法很巧妙:由于有要删除的j结点的指针,因此可以很容易得到j结点的后一个结点k结点的指针,只要把k结点的内容复制给i结点,然后删除k结点即可。
但是要注意!如果链表只有一个结点,head指针要指NULL;如果要删除的是尾结点,即后面没有结点了,那么也只能从头开始遍历。

1 #include <iostream> 2 using namespace std; 3 4 5 class Node 6 { 7 public: 8 Node(int v, Node* n) 9 {val = v; 10 next = n;} 11 ~Node(){} 12 int val; 13 Node* next; 14 }; 15 Node * phead = NULL; 16 17 void AddNode(int val) 18 { 19 Node* pnode = new Node(val,NULL); 20 //Node one_node(val,NULL); 这里有大bug!如果这样写,在函数退出时自动调用析构函数!链表就乱了! 21 if(phead == NULL) 22 { 23 phead = pnode; 24 } 25 else 26 { 27 Node* p = phead; 28 while(p->next != NULL) 29 { 30 p = p->next; 31 } 32 p->next = pnode; 33 } 34 } 35 void PrintLink() 36 { 37 Node* p = phead; 38 while(p != NULL) 39 { 40 int temp = p->val; 41 cout<<temp<<endl; 42 p = p->next; 43 } 44 } 45 void DeleteNode(Node* pdelete) 46 { 47 Node * p; 48 if(phead == NULL || pdelete == NULL) //check 49 return; 50 51 if(pdelete == phead) //the node to be deleted is equal to the head 52 { 53 if(phead->next == NULL)//only one node 54 { 55 delete pdelete; 56 pdelete = NULL; 57 phead = NULL; 58 } 59 else //more than one node 60 { 61 phead = phead->next; 62 delete pdelete; 63 pdelete = NULL; 64 } 65 } 66 else if(pdelete->next == NULL) //the node to be deleted is the last node 67 { 68 p = phead; 69 while (p->next->next != NULL) p = p->next; //find the node before the last node 70 p->next = NULL; 71 delete pdelete; 72 pdelete = NULL; 73 } 74 else //the normal situation,not the head or the tail 75 { 76 Node* pnext = pdelete->next; 77 pdelete->val = pnext->val; 78 pdelete->next = pnext->next; 79 delete pnext; 80 pnext = NULL; 81 } 82 } 83 84 int main() 85 { 86 int val,del,flag; 87 Node* pdelete; 88 cin>>val; 89 while(val != 0) 90 { 91 AddNode(val); 92 cin>>val; 93 } 94 PrintLink(); 95 96 cout<<"Input the node number you want to delete:"<<endl; 97 cin>>del; 98 99 pdelete = phead; 100 if(phead == NULL) cout<<"No node!"<<endl; 101 102 flag = 1; 103 for(int i=0;i<del&&flag;i++) 104 { 105 if (pdelete->next!=NULL) pdelete = pdelete->next; 106 else 107 { 108 cout << "The node not exists!"<<endl; 109 flag=0; 110 } 111 } 112 if(flag) DeleteNode(pdelete); 113 PrintLink(); 114 115 return 0; 116 }