2012-12-08 203 views
0

我在Ç使用一種自我指涉的結構創建的列表,我想通了如何做好每一件事可能的列表中,但刪除最後一個元素,這是令人費解我現在幾個星期了,請幫我 這就是我所做的。 爲了得到這個程序的概念,你只需要看功能main,和Delete,也許insert。請注意,這個代碼是在Ubuntu上使用gcc編譯的。如何刪除列表中的最後一個元素用C

/* self-referencial structure */ 
struct ListNode 
{ 
    char data; 
struct ListNode *nextNode ; 
}; 


typedef struct ListNode ListNode; 
typedef ListNode *ListNodePtr ; 

/* function protypes */ 
void insert(ListNodePtr *sptr, char value); // insert element in list in alphabet order 
void Delete (ListNodePtr *sptr);// PROBLEM HERE; remove last element from list 
void printList(ListNodePtr);// output the contents of the list 
void instructions(); // print instruction on screen 

int main(void) 
{ 
ListNodePtr startPtr = NULL ; // there are initially no nodes 
int choice; 
char item ;// char to be placed in list 

/* Give instruction s and allow user to make a choice 
* insert , print, delete. 
*/ 
instructions(); 
printf("?"); 
scanf("%d", &choice); 

/* loop until sentinel value 3 */ 
while (!(choice == 4)) 
{ 
    switch(choice) 
    { 
    case 1: 
     printf("Enter a character"); 
     scanf("\n%c",&item); 
     insert(&startPtr, item); 
     printList(startPtr); 
     break ; 

    case 2: 
     /* If the list is not empty */ 
     Delete(&startPtr); 
     printList(startPtr); 
     // if it is printf("the list is empty"); 
     break; 
    case 3: 
     printList(startPtr); 
     break; 
    default: 
     printf("Invalid choice"); 
     break; 
    }// end switch 
    printf("?"); 
    scanf("%d",&choice); 
}// end while 
return 0 ; 
}// END FUNCTION MAIN 

/* display program choices/instruction to user */ 
void instructions(void) 
{ 
    printf("Enter your choice:\n" 
    "1 to insert an element into the list.\n" 
    "2 to delete an element from the list.\n" 
    "3 to print the list\n" 
    "4 to end.\n"); 
} 

void insert(ListNodePtr *sptr, char value) 
{ 
ListNodePtr currentPtr; 
ListNodePtr previousPtr; 
ListNodePtr newNode ; 


/* create an area in memory the size of ListNode and 
*allocate to newPtr */ 
newNode = malloc(sizeof(ListNode)); // create new node 

// if space is available 
if (newNode != NULL) 
{ 
    newNode->data = value; 
    newNode->nextNode = NULL; 

    previousPtr = NULL ; 
    currentPtr = *sptr ; 

    /* walk to correct location in the list */ 
    while (currentPtr != NULL && value > currentPtr->data) 
    { 
     previousPtr = currentPtr; 
     currentPtr = currentPtr->nextNode; 
    }// end while 

    /* insert node at beginning of the list */ 
    if(previousPtr == NULL) 
    { 
     newNode->nextNode = *sptr; 
     *sptr = newNode; 
    }// end if 

    else 
    { 
     previousPtr->nextNode = newNode; 
     newNode->nextNode = currentPtr ; 
    } 
}// end if 
else 
{ 
    printf("%c not inserted , memory not available", value); 
} 

} 

void Delete(ListNodePtr *sptr) 
{ 
ListNodePtr previousPtr; 
ListNodePtr currentPtr; 
ListNodePtr tempPtr; 

// if there is only one element 
if((*sptr)->nextNode == NULL) 
{ 
    tempPtr = *sptr; // hold on to Node being removed 
    *sptr = (*sptr)->nextNode; 
    free(tempPtr); 
} 
else 
{ 
    previousPtr = *sptr ; 
    currentPtr = (*sptr)->nextNode; 

    // walk to end of the list 
    while(currentPtr->nextNode != NULL) 
    { 
     previousPtr = *sptr; 
     currentPtr = currentPtr->nextNode; 
    } 

    if(currentPtr != NULL) 
    { 
     // WHAT DO I DO HERE ??!!?? 
     // if the list has more than one two elements, 
     // all but the first element is deleted 

     previousPtr->nextNode = currentPtr->nextNode; 
     currentPtr = NULL ; 
     free(currentPtr); 
    }// end if 
}// end else 


}// END FUNCTION DELETE 

void printList(ListNodePtr currentPtr) 
{ 
if(currentPtr == NULL) 
printf("List is empty"); 
else 
{ 
    while(currentPtr != NULL) 
    { 
     printf("%c --> ", currentPtr->data); 
     currentPtr = currentPtr->nextNode; 
    } /* end while */ 
     printf("NULL\n\n"); 
    /* end else */ 


} 
} 
+2

想想這意味着什麼來沒有下一個元素和如何影響您的最後一個感知的概念。在弄清楚之後,你應該沒有問題去搞清楚如何去除最後一個元素。 – RedX

+0

我明白最後一個元素必須指向NULL,並且在你試圖刪除之前,刪除最後一個元素,在NULL和節點之間刪除元素。但我不知道如果我錯誤地執行代碼,但我不能得到它。 – FutureSci

+0

實際上,您不必導航到最後一個節點,以查看是否後面跟着一個「NULL」節點。使用哨兵節點和雙向鏈表的 – 2012-12-08 22:33:57

回答

1

可能是這有助於

void Delete(ListNodePtr *sptr) 
{ 
ListNodePtr previousPtr; 
ListNodePtr currentPtr; 
ListNodePtr tempPtr; 

if((*sptr)->nextNode == NULL) 
{ 
    tempPtr = *sptr; // hold on to Node being removed 
    *sptr = (*sptr)->nextNode; 
    free(tempPtr); 
} 
else 
{ 
previousPtr = *sptr ; 
currentPtr = (*sptr)->nextNode; 

// walk to end of the list 
while(currentPtr->nextNode != NULL) 
{ 
    previousPtr=previousPtr->nextNode;//this always points to the previous node 
    currentPtr = currentPtr->nextNode; 
} 

//after loop ends currentPtr points to the last node 

if(currentPtr != NULL) 
{ 
    previousPtr->nextNode=NULL;//This deletes the currentPtr from the list 
    free(currentPtr); 
}// end if 
}// end else 
}// END FUNCTION DELETE 
+0

謝謝。另一種方法,我發現它可以做到的是通過移動到倒數第二個元素(不是最後一個),分配previousPtr-> nextPtr = currentPtr-> nextPtr;然後釋放currentPtr。 – FutureSci

相關問題