Ich versuche gerade, einen Knoten aus einer doppelt verknüpften Liste zu löschen, aber wenn nur ein Element übrig ist, löst es eine Zugriffsverletzungsausnahme beim Versuch, es in Zeile 11 (*sPtr)->prevPtr = NULL;
zu löschen. Dies ist meine aktuelle Löschfunktion:So löschen Sie den Knoten aus der doppelt verknüpften Liste
char del(ListNodePtr *sPtr, char value)
{
ListNodePtr previousPtr; /* pointer to previous node in list */
ListNodePtr currentPtr; /* pointer to current node in list */
ListNodePtr tempPtr; /* temporary node pointer */
/* delete first node */
if (value == (*sPtr)->data) {
tempPtr = *sPtr; /* hold onto node being removed */
*sPtr = (*sPtr)->nextPtr; /* de-thread the node */
(*sPtr)->prevPtr = NULL;
if ((*sPtr)->nextPtr != NULL) {
free(tempPtr); /* free the de-threaded node */
}
return value;
} /* end if */
else {
previousPtr = *sPtr;
currentPtr = (*sPtr)->nextPtr;
/* loop to find the correct location in the list */
while (currentPtr != NULL && currentPtr->data != value) {
previousPtr = currentPtr; /* walk to ... */
currentPtr = currentPtr->nextPtr; /* ... next node */
} /* end while */
/* delete node at currentPtr */
if (currentPtr != NULL) {
tempPtr = currentPtr;
previousPtr->nextPtr = currentPtr->nextPtr;
free(tempPtr);
return value;
} /* end if */
} /* end else */
return '\0';
}
EDIT: Ich werde meine Hauptfunktion und meine Druckfunktion in dieser Reihenfolge hinzufügen unten für eine besseren Rahmen das, was ich versuche, so zu tun, dass meine Frage wieder geöffnet werden kann:
hier ist meine Hauptfunktion mit meiner listNode Struktur:
struct listNode {
char data; /* each listNode contains a character */
struct listNode *nextPtr; /* pointer to next node*/
struct listNode *prevPtr; /* pointer to previous node*/
}; /* end structure listNode */
typedef struct listNode ListNode; /* synonym for struct listNode */
typedef ListNode *ListNodePtr; /* synonym for ListNode* */
/* prototypes */
void insert(ListNodePtr *sPtr, char value);
char del(ListNodePtr *sPtr, char value);
int isEmpty(ListNodePtr sPtr);
void printList(ListNodePtr currentPtr);
void printReverse(ListNodePtr currentPtr);
void instructions(void);
int main(void)
{
ListNodePtr startPtr = NULL; /* initially there are no nodes */
int choice; /* user's choice */
char item; /* char entered by user */
instructions(); /* display the menu */
printf("? ");
scanf("%d", &choice);
/* loop while user does not choose 3 */
while (choice != 3) {
switch (choice) {
case 1:
printf("Enter a character: ");
scanf("\n%c", &item);
insert(&startPtr, item); /* insert item in list */
printList(startPtr);
printReverse(startPtr);
break;
case 2:
/* if list is not empty */
if (!isEmpty(startPtr)) {
printf("Enter character to be deleted: ");
scanf("\n%c", &item);
/* if character is found, remove it */
if (del(&startPtr, item)) { /* remove item */
printf("%c deleted.\n", item);
printList(startPtr);
printReverse(startPtr);
} /* end if */
else {
printf("%c not found.\n\n", item);
} /* end else */
} /* end if */
else {
printf("List is empty.\n\n");
} /* end else */
break;
default:
printf("Invalid choice.\n\n");
instructions();
break;
} /* end switch */
printf("? ");
scanf("%d", &choice);
} /* end while */
printf("End of run.\n");
return 0; /* indicates successful termination */
} /* end main */
und hier meine printReverse und drucken Funktionen sind:
void printList(ListNodePtr currentPtr)
{
/* if list is empty */
if (currentPtr == NULL) {
printf("List is empty.\n\n");
} /* end if */
else {
printf("The list is:\n");
/* while not the end of the list */
while (currentPtr != NULL) {
printf("%c --> ", currentPtr->data);
currentPtr = currentPtr->nextPtr;
} /* end while */
printf("NULL\n\n");
} /* end else */
} /* end function printList */
void printReverse(ListNodePtr currentPtr)
{
/* if list is empty */
if (currentPtr == NULL) {
printf("List is empty.\n\n");
} /* end if */
else {
printf("The list in reverse is:\n");
while (currentPtr->nextPtr != NULL)
currentPtr = currentPtr->nextPtr;
/* while not the beginning of the list */
while (currentPtr != NULL) {
printf("%c --> ", currentPtr->data);
currentPtr = currentPtr->prevPtr;
} /* end while */
printf("NULL\n\n");
} /* end else */
} /* end function printList */
Ich hoffe wirklich, dies macht es klarer über alles, was passiert, weil ich seit 3 Tagen daran festhalte und es gibt wenig bis keine Themen, die ich online finden kann, die darüber reden, wie ich das mache , weil die Liste beim Einfügen und Löschen alphabetisch sortiert ist.
Also wenn jemand versuchen kann, mir zu sagen, was falsch ist und warum es eine Zugriffsverletzung Ausnahme in Zeile 11 löst, wenn ich versuche, das letzte Element in der Liste zu löschen, wäre ich so dankbar. Vielen Dank!
Nicht geprüft, es ist wahrscheinlich, weil '(* SPTR) -> nextPtr', die' * sPtr' assinged ist, war 'NULL' weil nur ein Knoten übrig ist. – MikeCAT
@MikeCAT wo repariere ich das an obwohl? –
Wenn Sie keinen Kopf (für eine einfach verknüpfte Liste) und keinen Schwanz (beide für eine doppelt verkettete Liste) haben, würde ich sie sehr empfehlen. Ich weiß nicht, wie jemand verknüpfte Listen ohne sie macht. Das Einfügen und Löschen von Knoten ist ein Sonderfall, wenn Sie 0 oder 1 Elemente in der Liste haben, was bei der Pflege von Kopf- und Endzeigern viel einfacher ist. Obwohl ich gesagt habe, dass ich hier sicher bin, dass jemand hier Lust hat und verlinkte Listen ohne sie macht. – yano