2017-04-16 6 views
1

Ich habe eine sehr einfache Funktion, um den maximalen, nicht negativen Wert eines ganzen Zahlenstapels herauszufinden. Ich möchte diese Funktion in eine rekursive transformieren. Es gibt mehr Punkte im Auge zu behalten:Rekursive Funktion auf Stack

  • Bevor die Funktion ausgeführt wird, haben wir num initialisiert, haben aber keinen Wert zugewiesen. Und bitte, sollten wir nicht darauf verlassen, dass C automatisch 0-num unter bestimmten Bedingungen
  • Nach dem Ausführen der Funktion des Stapel s leer vergeben werden und wir haben den maximalen nicht negativen Wert gespeichert in num
  • I ist ein Anfänger in C und Datenstrukturen, also bitte schön :)

Dies ist die iterative Funktion:

void max_stack(stack *s, int *num){ 
    *num = 0; 
    int aux = 0; 
    while (!emptyStack(*s)){ 
     aux = top(*s); 
     pop(s); 
     if (aux>*num){ 
      *num = aux; 
     } 
    } 
} 
+1

Ich habe keine Ahnung hat, warum diese auf ein zu transformieren wollen würde rekursive Funktion, wenn die Lösung, die Sie jetzt haben, besser für C passt als die rekursive Funktion wäre ... –

+0

@AnttiHaapala Hausaufgabenanforderungen vielleicht? –

+1

@AnttiHappala: Ich versuche Rekursion besser zu verstehen und möchte fließender von iterativen Funktionen zu rekursiven und umgekehrt. Das ist es. Der Zweck dieser Frage ist zu lernen. Die Einschränkungen, die ich aufgezählt habe, sollen sicherstellen, dass die beiden Funktionen 100% äquivalent sind. – Peter

Antwort

2

genau der iterativen Code zur Verfügung gestellt, um übereinstimmen, müssen wir auch überein die Annahme, dass 0 auch bei einem leeren Stack der Mindestwert ist, der im Zielparameter gespeichert wird.

Damit:

void recursive_max_stack(stack *s, int *num) 
{ 
    if (emptyStack(*s)) 
    { 
     *num = 0; 
     return; 
    } 

    int lhs = top(*s); 
    pop(s); 

    recursive_max_stack(s, num); 

    if (lhs > *num) 
     *num = lhs; 
} 

Erklärung

Zuerst müssen wir einen Standardfall (wenn es keine Elemente in dem Stapel). Genau wie Ihre iterative Funktion speichert der Standardfall als Ergebnis null.

if (emptyStack(*s)) 
{ 
    *num = 0; 
    return; 
} 

Also müssen wir den aktuellen Stack oben im aktuellen Rahmen sparen, dann, dass der Stapel Pop-off (denken Sie daran, wir halten es in einer lokalen Variablen):

lhs = top(*s); 
pop(s); 

Sobald das ist fertig, wir können rekrutieren.

recursive_max_stack(s, num); 

Wenn von der Rekursion der Rückkehr jedes lhs wird mit dem Inhalt des *num verglichen (die 0 eingestellt wurde, als man die maximale Tiefe Hit). Wenn größer, ersetzt lhs den unter *num gespeicherten Wert.

if (lhs > *num) 
    *num = lhs; 

Damit setzt sich der Call-Stack, wie wir Invokes entspannen, schließlich in die Anfangs invoke Rückkehr, dann mit dem Anrufer, mit *num jetzt, was die größte nicht-negativen Wert in dem Stapel halten war, oder Null, wenn alle Werte waren negativ (oder der Stapel war leer).

Das ist es. Es ist egal, welcher ursprüngliche Wert in *num gespeichert wurde. Es wird schließlich durch 0 bei Erreichen maximale Rekursionstiefe ersetzt, ersetzt dann wieder, wenn der nachfolgende Rahmen ein lhs Wert größer als der aktuelle gespeicherte Wert in *num

+0

Hervorragende Erklärung. Der einzige Zweifel, den ich habe, ist, warum brauchen wir die "Rückkehr" nach "* num = 0" – Peter

+0

@Peter Putting alles * Vergangenheit *, dass in einem "else" Block würde diese Rückkehr mot machen. Es ist nur eine Stilwahl. Sie können es auf jede Art und Weise tun, aber Sie sollten NICHT einfach die 'return;' entfernen und den Code so lassen, wie er ist. Es wird nicht funktionieren. – WhozCraig

0

Das funktioniert, wenn der Stapel nicht leer ist, dann ruft er sich selbst weiter und übergibt den größten Wert weiter. Sobald der Stapel leer ist, werden die Funktionen nacheinander zurückgegeben, wobei der größte Wert durch den Zahlzeiger zurückgegeben wird.

Hier in Pseudo-Code:

void max_stack(stack *s, int * num){ 
    int aux = 0; 
    if(!emptyStack(*s)){ 
     aux = top(*s); 
     pop(s); 
     if (aux > (*num)){ 
      (*num) = aux; 
     } 
     max_stack(s, num); 
    } 
} 

Wenn er zum ersten Aufruf dieser Funktion können Sie es wie so nennen würde:

int num = 0 
max_stack(s, &num); 
+0

@Josep Ich änderte num auf einen Zeiger, sollte es noch funktionieren – Archmede

+0

@Josep Ich habe auch einen Fehler von der vorherigen Version behoben – Archmede

+0

danke viel für deine Antwort. Beachten Sie jedoch, dass die Funktion nicht zu 100% der von mir geposteten iterativen Funktion entspricht. Der Schlüsselpunkt ist, dass die "void" -Funktion unempfindlich gegenüber dem Anfangswert von num sein sollte: alles was wir vor dem Aufruf der Funktion tun können ist 'int num;' – Peter