如何删除链表中的节点?
Posted
技术标签:
【中文标题】如何删除链表中的节点?【英文标题】:How to delete a node in a linked list? 【发布时间】:2018-05-09 12:56:18 【问题描述】:这是我目前所拥有的,但它不起作用。基本上跳到else if(cnode == preposition)
。
void LinkedList::Delete(Node *PrePosition)
Node *cnode = head;
Node *pnode = NULL;
while (cnode != NULL)
if (cnode->value != NULL)
if (pnode == NULL)
// if there is not previous node
head = cnode->next;
else if (cnode == PrePosition)
// if there is previous node
cout << endl << "Deleting: " << cnode << endl;
pnode->next = cnode->next;
else
// don't delete
pnode = cnode;
cnode = cnode->next;
【问题讨论】:
如果PrePosition
真的是要删除的节点之前的节点,那么这看起来更像是对常识的测试。但这可能永远是提问者的秘密。
【参考方案1】:
1:从上一个节点中取出指针,指向要删除的节点之后的下一个节点
2:删除上一个节点指向当前节点的指针
3:删除从下一个节点指向当前节点的指针(如果是双向链表)
【讨论】:
【参考方案2】:单链表删除的三种情况:
删除第一个节点
void delete_first()
node *temp=new node;
temp=head;
head=head->next;
delete temp;
删除最后一个节点
void delete_last()
node *current = new node;
node *previous = new node;
current=head;
while(current->next != NULL)
previous = current;
current = current->next;
tail = previous; // if you have a Node* tail member in your LinkedList
previous->next = NULL;
delete current;
在特定位置删除(您的情况)
void LinkedList::delete_position(int pos)
node *current=new node;
node *previous=new node;
current=head;
for(int i=1; i < pos; i++) //or i = 0; i < pos-1
previous=current;
current=current->next;
previous->next=current->next;
delete current;
^^ 来自codementor ^^
但是,如果您的函数签名打算使用 delete_node(Node* nodeToDelete)
[PrePosition 在这种情况下不是一个好名字],并且您想删除传递给函数的节点而不知道它在列表中的位置,我们可以像这样修改 delete_position():
void LinkedList::delete_node(Node* nodeToDelete)
node *current= head;
node *previous= nullptr;
if (head == nodeToDelete)
head = nodeToDelete->next;
delete nodeToDelete;
return
//else
while(current != nodeToDelete)
previous = current;
current = current->next
previous->next = current->next;
delete nodeToDelete;
同样在您的原始代码中,如果它跳过了您提到的那一行,当 cnode 中包含非空值时,pnode 始终为空。
【讨论】:
如果你已经有一个指向前一个位置的指针,为什么要迭代列表来找到它? @user4581301 因为它是一个单链表,所以你不能只删除指针。您必须迭代才能找到前一个节点。我认为虽然我在 OPs 的情况下假设错误,但指针很可能是它的名字所暗示的:指向要删除的节点之前的节点的指针。 有一个非常巧妙的技巧,可以使用指向指针的指针来解决这个问题。与其传入指向要删除的节点的指针,不如传入指向所需下一个指针的指针更新。函数看起来像void LinkedList::delete_node(Node** nodeToDelete) if (*nodeToDelete) node * temp = *nodeToDelete; *nodeToDelete = (*nodeToDelete)->next; delete temp;
Variant of the alternative provided here.(***.com/a/22122095/4581301)【参考方案3】:
这里是完整的代码
class SportShoe
private:
struct nodeSport
int ShoeID;
char BrandShoe[SIZE];
char TypeShoe[SIZE];
char ColourShoe[SIZE];
int SizeShoe;
float PriceShoe;
nodeSport *last;
;
nodeSport *first = NULL;
public:
int MenuSportShoe();
void AddSportShoe();
void DisplaySportShoe();
void DeleteSportShoe();
static void ExitSportShoe();
;
int SportShoe::MenuSportShoe()
int OptionSportShoe = 0;
cout << endl;
cout << "Please select from the menu:" << endl;
cout << ":: 1 :: Add item to shoe list" << endl;
cout << ":: 2 :: Display shoes list" << endl;
cout << ":: 3 :: Delete item from the list" << endl;
cout << ":: 4 :: Back" << endl;
cout << "=>> ";
cin >> OptionSportShoe;
while (OptionSportShoe == 1)
AddSportShoe();
while (OptionSportShoe == 2)
DisplaySportShoe();
while (OptionSportShoe == 3)
DeleteSportShoe();
while (OptionSportShoe == 4)
ExitSportShoe();
return 0;
void SportShoe::AddSportShoe()
nodeSport *tempShoe1, *tempShoe2;
tempShoe1 = new nodeSport;
cout << "Please enter the Shoe ID : (eg. 43210) " << endl;
cout << "=>> ";
cin >> tempShoe1->ShoeID;
cout << "Please enter the Shoe Brand: (eg. Adidas) " << endl;
cout << "=>> ";
cin.sync();
cin.getline(tempShoe1->BrandShoe,SIZE);
cout << "Please enter the Shoe Type : (eg. Running) " << endl;
cout << "=>> ";
cin.sync();
cin.getline(tempShoe1->TypeShoe,SIZE);
cout << "What is the Shoe Colour : (eg. Grey) " << endl;
cout << "=>> ";
cin.sync();
cin.getline(tempShoe1->ColourShoe,SIZE);
cout << "Please enter Shoe Size : (eg. 9) " << endl;
cout << "=>> ";
cin >> tempShoe1->SizeShoe;
cout << "Please enter the price of the Shoe : (eg. RM123.45) " << endl;
cout << "=>> RM ";
cin >> tempShoe1->PriceShoe;
tempShoe1->last = NULL;
if (first == NULL)
first = tempShoe1;
else
tempShoe2 = first;
while (tempShoe2->last != NULL)
tempShoe2 = tempShoe2->last;
tempShoe2->last = tempShoe1;
system("PAUSE");
MenuSportShoe();
void SportShoe::DisplaySportShoe()
nodeSport *tempShoe1;
tempShoe1 = first;
while(tempShoe1)
cout << "ID : " << tempShoe1->ShoeID << endl;
cout << "Brand : " << tempShoe1->BrandShoe << endl;
cout << "Type : " << tempShoe1->TypeShoe << endl;
cout << "Colour : " << tempShoe1->ColourShoe << endl;
cout << "Size : " << tempShoe1->SizeShoe << endl;
cout << "Price : " << tempShoe1->PriceShoe << endl;
cout << endl;
tempShoe1 = tempShoe1->last;
system("PAUSE");
MenuSportShoe();
void SportShoe::DeleteSportShoe()
nodeSport *tempShoe1, *tempShoe2;
int DataShoe;
tempShoe2 = tempShoe1 = first;
if(tempShoe1 == NULL)
cout << "\nList is empty!" << endl;
system("PAUSE");
MenuSportShoe();
while(tempShoe1 != NULL)
cout << "\nEnter the Shoes ID to be deleted: (eg. 123) ";
cin >> DataShoe;
tempShoe2 = tempShoe1;
tempShoe1 = tempShoe1->last;
if(DataShoe == tempShoe1-> ShoeID)
if(tempShoe1 == first)
first = first->last;
cout << "\nData deleted ";
else
tempShoe2->last = tempShoe1->last;
if(tempShoe1->last == NULL)
tempShoe2 = tempShoe2;
cout << "\nData deleted ";
delete(tempShoe1);
system("PAUSE");
MenuSportShoe();
else
cout << "\nRecord not Found!!!" << endl;
system("PAUSE");
MenuSportShoe();
void SportShoe::ExitSportShoe()
int sepatu;
cout << endl;
cout << "Please choose the option below."<<endl;
cout << ":: 1 :: Sport Shoe." << endl;
cout << ":: 2 :: Ladies High Heel." << endl;
cout << ":: 3 :: Exit" << endl;
cout << "=>> ";
cin >> sepatu;
while(sepatu == 1)
SportShoe listShoe;
listShoe.MenuSportShoe();
while(sepatu == 2)
HighHeel listShoe;
listShoe.MenuHighHeel();
while(sepatu == 3)
cout << "Thank you. Till we meet again."<< endl;
exit(1);
main()
cout << "Hello! Welcome to MySepatu Online Shop administrator."<< endl;
cout << endl;
SportShoe::ExitSportShoe();
HighHeel::ExitHighHeel();
return 0;
【讨论】:
【参考方案4】:public class linkedList
int count = 0;
class Node
int element;
Node next;
Node(int element)
this.element = element;
Node head = null;
Node tail = null;
public void addNode(int Object)
Node newNode = new Node(Object);
if (head == null)
head = tail = newNode;
else
tail.next = newNode;
tail = newNode;
public void Display()
Node current = head;
while (current!=null)
System.out.println(current.element);
count ++;
current = current.next;
public void Length()
System.out.println(count);
public void Remove(int node)
Node curr = head;
while (curr!=null) // looping the nodes
if (curr.element == node )
curr.element = curr.next.element;
curr = curr.next;
// To fix the Duplicates
while (curr!= tail)
curr.element = curr.next.element;
curr = curr.next;
RemoveEnd();
break;
curr = curr.next;
public void RemoveEnd()
Node current3 = head;
while (current3.next != tail)
current3 = current3.next;
tail = current3;
tail.next = null;
【讨论】:
你好杜夫。欢迎来到堆栈溢出。正如您可能已经看到的,它是关于解决编码问题的。当一个问题(及其答案)更多地是关于做“某人的家庭作业”(这已经发生在我身上)时,它们通常会被标记。我真的很困惑这个问题没有被标记,但我想它有一些价值。 请阅读“投票最多”的答案,因为您对特定问题(删除节点)的回答不正确,或者至少效率不高,因为您实际上是将所有数据移入当您只需要从中删除一项时的列表。请修正,否则您的答案将被否决。 即使您的答案背后的想法可能适用,它是在 Java 中,而 OP 正在寻求 C++ 中的解决方案。以上是关于如何删除链表中的节点?的主要内容,如果未能解决你的问题,请参考以下文章