2013-03-24 3 views
1

Итак, я искал форумы, но я все еще очень новичок в языке и связанных списках, поэтому я едва могу расшифровать результаты.Удаление узла в связанном списке C++

В основном я сделал функцию удаления для связанного списка. Теперь я могу создать список, пройти список, отсортировать список, выполнить поиск по списку и вставить перед любым узлом связанного списка. Я переработал код из вставки, чтобы найти точку в списке, где я мог бы удалить. Мое основное недоумение заключается в том, как связать предыдущие точки с узлом, который после того, который я удаляю.

+0

Если у вас возникли проблемы при записи кода, чтобы сделать то, что вы хотите, попробуйте решить проблему. Я нахожу, что это очень помогает мне. Кроме того, попробуйте отступы, это упрощает чтение кода. – Wug

+1

Поиск на этом сайте для «Удаление узла в связанном списке» дает массу результатов, безусловно, один из них должен быть вам полезен? – stijn

+0

Один намек: посмотрите на цикл while ... он проверяет, чтобы 'akey! = Entry-> adata'. Затем * внутри * этот цикл, вы проверяете, есть ли 'entry-> adata == akey'. Спросите себя, будет ли это «если» когда-либо выполняться. –

ответ

4

Я не буду писать реализацию целого нового связанного списка, но я могу указать на некоторые проблемы с кодом для вас.

Хитрость заключается в том, чтобы оставаться на одном узле впереди того, который вы хотите удалить.

Я переименовал entry в current для ясности

nodetype *current , *first, *next; 
int akey; 

// With this line your search will start from the second element. 
// current =start->ptr; 
// Should be 
current = start; 

// this is not needed. I am assuming the last node has NULL value for '->ptr' 
// last=start; 
next = current->ptr; 

cout<<"Input Data You Would Like To Delete"<<endl; 
cin>>akey; 

// Check if the first node contains the data 
// Assuming the list will have at least one element. i.e. current is not NULL 
while (current->adata == akey) 
{ 
    // Delete it. 
    delete current; 
    // Update current for the while loop 
    current = next; 
    // update next too. 
    next = current->ptr; 
} 
// Now we know the first element doesn't contain the data. 
// Update the pointer to the begging of the new list if anything is removed from the top. 
first = current; 

// This has unnecessary checks. 
// ****Specifically (akey!=current->adata) will 
// prevent you from entering the loop if it is false. 
// while((akey!=current->adata)&&(current->ptr !=NULL)) 
while(next != NULL) // This should be enough 
{ 
    if(next->adata == akey) 
    { 
      // make the current node (before the 'deletion point') 
      // lined to the one after the 'deletion point (next of the next) 
      current->ptr = next->ptr; 
      // delete the node. 
      delete next; 
      // Make the next pointer point to the new next. 
      next = current->ptr 
    } 
    // Otherwise advance both current and next. 
    else { 
      current = next; 
      next = next->ptr; 
    } 
} 

// Use this to test it. 
current = first; 
while(current){ 
    cout<<current->adata<<", "; 
    current = current->ptr; 
} 

Это не самый чистый путь. Однако это похоже на вашу реализацию, чтобы вы могли видеть, где вы поступили неправильно.

+0

см. Stardust, программа все еще падает после меня после компиляции и запуска. –

+0

ОК. Позвольте мне попробовать запустить его здесь. Я еще не тестировал его. – 2013-03-24 20:53:12

+0

Я могу выслать вам весь код, если вам понравится –

0

Рассмотрим структуру приведенной ниже,

struct info 
{ 
int data; 
struct info *next; 
}; 

если использовать вышеуказанную структуру для хранения записей в связанном списке, то следующий код может быть использован для удаления элементов из вашего связанного списка,

void delitem() 
{ 
    info *curr,*prev; 
    int tdata; 
    if(head==NULL) 
    { 
    cout<<"\nNo Records to Delete!!!"; 
    } 
    cout<<"\nEnter the Data to be deleted: "; 
    cin>>tdata; 
    prev=curr=head; 
    while((curr!=NULL)&&(curr->data!=tdata)) 
    { 
    prev=curr; 
    curr=curr->next; 
    } 
    if(curr==NULL) 
    { 
    cout<<"\nRecord not Found!!!"; 
    return; 
    } 
    if(curr==head) 
    { 
    head=head->next; 
    cout<<"\nData deleted: "<<tdata; 
    } 
    else 
    { 
    prev->next=curr->next; 
    if(curr->next==NULL) 
    { 
     temp=prev; 
    } 
    cout<<"\nData deleted: "<<tdata; 
    } 
    delete(curr); 
} 
+0

Я обновил свой вопрос, объявив структуру и функции void. Deepu, что делает head =? Я супер новичок. Спасибо вам, Wug и Deepu, я очень ценю вас обоих! –

+0

Глава будет содержать адрес первого элемента в связанном списке. – Deepu

+0

Что такое temp, объявленный как? – Damian

3
#include <iostream> 
#include <string> 
             // blank line(s) after includes 

using namespace std;      // some people will say to avoid this 
             // but I use it in examples for brevity 

             // blank line(s) around class def 
class nodetype 
{          // bracket on its own line 
public:         // non indented visibility specifier 
    nodetype(int value, nodetype *p)  // constructor first declared in class 
    { 
     adata = value;     // level of indentation for fn body 
     ptr = p;      // spaces around operators like = 
    } 
             // blank line(s) between fns and vars 
    int adata; 
    nodetype *ptr; 
}; 
             // blank line(s) between class and fn 
void LinkedListDelete(nodetype **start, int akey) 
{ 
    nodetype *current, **previous;  // pointer *s are connected to vars 
             // blank line between section 
    previous = start; 
    current = *start; 
             // blank line between section 
             // I use blank lines a lot, they help 
             // me to organize my thoughts 

    while((current != NULL) && (akey != current->adata)) 
    {         // indentation inside nested scope 
     previous = &current->ptr;  // no space for unary operators like & 
     current = current->ptr;   // assignments justified to same level 
    } 

    if (current != NULL) 
    { 
     *previous = current->ptr;  // no space for unary *, space for = 
     delete current; 
    } 
             // more blank lines between sections 
    return; 
} 

void LinkedListPrint(nodetype *list)  // no space for unary * 
{          // brackets on their own lines 
    while (list != NULL)     // space around != 
    { 
     cout << "(Node: " << list->adata << ") "; 
     list = list->ptr;    // spaces around << 
    } 
    cout << endl; 
} 

int main() 
{ 
    nodetype *node = new nodetype(5, new nodetype(10, // justified stuff 
        new nodetype(7, new nodetype(14, 
        new nodetype(23, NULL))))); 
             // blank lines 
    cout << "Build linked list: "; 
    LinkedListPrint(node); 
    cout << "Removed node 7: "; 
    LinkedListDelete(&node, 7); 
    LinkedListPrint(node); 

    return 0; 
} 

Я сделал этот код на основе кода, который вы указали. Это не совсем то же самое, я изменил некоторые вещи, но он делает то, что вы хотите. Я должен был догадаться, какова структура nodetype, и я добавил конструктор для моего удобства. Я добавил несколько замечаний, указывающих на аспекты моего стиля.

Обратите внимание, что это легче читать, чем код, который вы изначально предоставили. Стиль важен. Люди скажут вам, что вам нужно использовать стиль X или Y, но важно то, что вы выбираете любой стиль, который вам нравится, и придерживайтесь его последовательно; это облегчит вам быстрый и быстрый анализ вашего собственного кода.

Поверьте мне, когда вы написали много кода, вы перестаете быть в состоянии запомнить все это сразу, и возможность выяснить, что вы делаете быстро, имеет важное значение.

+0

отличное кодирование :) – StarDust

0

Я думаю, что это слишком просто и легко удалить узел или вставить ine в связанный список, но для этого требуется точное понимание его МЕХАНИЗМА. Этот пример показывает, как добавлять и удалять узлы, однако это не полная программа, но она раскрывает механизм добавления и удаления и перемещения alinked-лист:

#include <iostream> 
using namespace std; 

//class Data to store ages. in a real program this class can be any other 
//class for example a student class or customer... 
class Data 
     { 
     public: 
       Data(int age):itsAge(age){} 
       ~Data(){} 
       void SetAge(int age){itsAge=age;} 
       int getAge()const{return itsAge;} 
     private: 
       int itsAge; 
     }; 

//the most important part of the program is the linked0list 
class Node 
      { 
      public: 
       //we just make itsPtrHead when created points to Null even if we pass a pointer to Data that is not NULL 
       Node(Data* pData): itsPtrData(pData),itsPtrHead(NULL),itsCount(0){} 

       Data* getPdata()const; 
       Node* getPnext()const; 
       int getCount()const{return itsCount;} 

       void insertNode(Data*);//import bcause it shoes the mechanism of linked-list 
       void deleteNode(int);//most significant in this program 
       Data* findData(int&,int); 
       void print()const; 
     private: 
       Data* itsPtrData; 
       Node* itsPtrHead; 
       int itsCount; 

      }; 

Data* Node::getPdata()const 
{ 
if(itsPtrData) 
    return itsPtrData; 
else 
    return NULL; 
} 
Node* Node::getPnext()const 
{ 
return itsPtrHead; 
} 
void Node::insertNode(Data* pData) 
{ 
Node* pNode=new Node(pData);//create a node 
Node* pCurrent=itsPtrHead;//current node which points first to the first node that is the "head bode" 
Node* pNext=NULL;//the next node 

int NewAge=pData->getAge();//the new age that is past to insertNode function 
int NextAge=0;//next age 
itsCount++;//incrementing the number of nodes 

//first we check wether the head node "itsPtrHead" points NULL or not 
//so if it is null then we assign it the new node "pNode" and return from insert function 
if(!itsPtrHead) 
    { 
    itsPtrHead=pNode; 
    return; 
    } 
//if the condition above fails (head is not null) then check its value and 
//compare it with new age and if the new one is smaller than the head 
//make this new one the head and then the original node that head points to it make it its next node to the head 
if(itsPtrHead->getPdata()->getAge() > NewAge) 
    { 
    pNode->itsPtrHead=itsPtrHead; 
    itsPtrHead=pNode; 
    //exit the function 
    return; 
    } 
//if the condition above fails than we move to the next node and so on 
for(;;) 
    { 
    //if the next node to the current node is null the we set it with this new node(pNode) and exit 
    if(!pCurrent->itsPtrHead) 
     { 
     pCurrent->itsPtrHead=pNode; 
     return; 
     } 
    //else if it not null(next node to current node) 
    //then we compare the next node and new node 
    pNext=pCurrent->itsPtrHead; 
    NextAge=pNext->getPdata()->getAge(); 
    //if next node's age is greater than new then we want new node 
    //to be the next node to current node then make the original next to current to be the next to its next 
    if(NextAge > NewAge) 
     { 
     pCurrent->itsPtrHead=pNode; 
     pNode->itsPtrHead=pNext; 
     //exitting 
     return; 
     } 
    //if no condition succeeds above then move to next node and continue until last node 
    pCurrent=pNext; 
    } 
} 
// delete a node is a bit different from inserting a node 
void Node::deleteNode(int age) 
{  
//deleting a node is much like adding one the differecne is a bit trickier 
Node* pTmp=itsPtrHead; 
Node* pCurrent=itsPtrHead; 
Node* pNext=NULL; 

//1 checking for wether age (node contains age) to be deleted does exist 
for(;pTmp;pTmp=pTmp->itsPtrHead) 
    { 
    if(pTmp->getPdata()->getAge() == age) 
     break; 
    } 
//if age to be deleted doesn't exist pop up a message and return 
if(!pTmp) 
    { 
    cout<<age<<": Can't be found!\n"; 
    return; 
    } 

int NextAge=0; 

for(;;) 
    { 
    //if age to be deleted is on the head node 
    if(itsPtrHead->getPdata()->getAge() == age) 
     { 
     //store the next to head node 
     pTmp=itsPtrHead->itsPtrHead; 
     //delete head node 
     delete itsPtrHead; 
     //assign the head new node (node after the original head) 
     itsPtrHead=pTmp; 
     //decrement the count of nodes 
     itsCount--; 
     //exiting gracefully 
     return; 
     } 
    //moving to next node 
    pNext=pCurrent->itsPtrHead; 
    NextAge=pNext->getPdata()->getAge(); 
    //checking next node age with age to be deleted. if they 
    //match delete the next node 
    if(NextAge == age) 
     { 
     //next node holds the target age so we want its NEXT node 
     //and store it in pTmp; 
     pTmp=pNext->itsPtrHead;//Next node of the target node 
     //pCurrent doesn't yet hold the target age but it is the 
     //previous node to target node 
     //change the next node of pCurrent so that it doesn't 
     //point to the target node but instead to the node right 
     //after it 
     pCurrent->itsPtrHead=pTmp; 
     //delete the target node (holds the target age) 
     delete pNext; 
     //decrement number of nodes 
     itsCount--; 
     //exit 
     return; 
     } 
    //if pNext doesn't point to target node move to the next node 
    //by making pCurrent points to the next node in the list 
    pCurrent=pNext; 
    } 

} 

void Node::print()const 
{ 
Node* pTmp=itsPtrHead; 
while(pTmp) 
    { 
    cout<<"age: "<<pTmp->getPdata()->getAge()<<endl; 
    pTmp=pTmp->itsPtrHead; 
    } 
} 
int main() 
{ 
//note this is not a real proram just we show how things works 

Data* pData=new Data(6); 
Node theNode(pData); 
theNode.print(); 
pData=new Data(19); 
theNode.insertNode(pData); 
pData=new Data(20); 
theNode.insertNode(pData); 
pData=new Data(23); 
theNode.insertNode(pData); 
pData=new Data(25); 
theNode.insertNode(pData); 
pData=new Data(30); 
theNode.insertNode(pData); 
pData=new Data(27); 
theNode.insertNode(pData); 
pData=new Data(33); 
theNode.insertNode(pData); 
pData=new Data(18); 
theNode.insertNode(pData); 

theNode.print(); 
cout<<endl<<endl; 

//int age; 
//int index; 
//cout<<"Age to finde: "; 
//cin>>age; 
//cout<<endl; 
//theNode.Find(index,age); 

//cout<<age<<" : Found on index: "<<index<<endl; 

//theNode.modify(age); 

//theNode.print(); 
int age; 
cout<<"age to delete: "; 
cin>>age; 
cout<<endl; 

theNode.deleteNode(age); 
theNode.print(); 

cout<<endl<<endl<<endl; 
return 0; 
} 
//modify and other member functions are not the purpose of this program