Quicksort: Η επιλογή του άξονα

ψήφοι
94

Κατά την εφαρμογή Quicksort, ένα από τα πράγματα που έχετε να κάνετε είναι να επιλέξετε ένα άξονα. Αλλά όταν βλέπω ψευδοκώδικα όπως το παρακάτω, δεν είναι σαφές πώς θα πρέπει να επιλέξετε τον άξονα. Πρώτο στοιχείο της λίστας; Κάτι άλλο?

 function quicksort(array)
     var list less, greater
     if length(array) ≤ 1  
         return array  
     select and remove a pivot value pivot from array
     for each x in array
         if x ≤ pivot then append x to less
         else append x to greater
     return concatenate(quicksort(less), pivot, quicksort(greater))

Μπορεί κάποιος να με βοηθήσει να κατανοήσουν την έννοια της επιλογής ενός άξονα και κατά πόσον ή όχι διαφορετικά σενάρια απαιτούν διαφορετικές στρατηγικές.

Δημοσιεύθηκε 02/10/2008 στις 20:37
πηγή χρήστη
Σε άλλες γλώσσες...                            


13 απαντήσεις

ψήφοι
72

Επιλέγοντας ένα τυχαίο άξονα ελαχιστοποιεί την πιθανότητα που θα συναντήσετε στη χειρότερη περίπτωση O (n 2 ) απόδοση (πάντα επιλέγοντας πρώτη ή η τελευταία θα μπορούσε να προκαλέσει την απόδοση χειρότερης περίπτωσης για σχεδόν διευθετηθεί ή σχεδόν αντίστροφη ταξινόμηση δεδομένα). Επιλέγοντας το μεσαίο στοιχείο θα είναι επίσης αποδεκτός στην πλειονότητα των περιπτώσεων.

Επίσης, αν έχετε την εφαρμογή της παρούσας εαυτό σας, υπάρχουν εκδοχές του αλγορίθμου που εργάζονται επί τόπου (δηλαδή χωρίς να δημιουργεί δύο νέες λίστες και στη συνέχεια να συνενώσει τους).

Απαντήθηκε 02/10/2008 στις 20:41
πηγή χρήστη

ψήφοι
47

Εξαρτάται από τις απαιτήσεις σας. Η επιλογή ενός άξονα τυχαία καθιστά πιο δύσκολο να δημιουργήσει ένα σύνολο δεδομένων που δημιουργεί O (Ν ^ 2) απόδοση. «Η μέση-of-τρία» (πρώτη, τελευταία, μέση) είναι επίσης ένας τρόπος για την αποφυγή προβλημάτων. Προσοχή σχετική απόδοση των συγκρίσεων, αν? αν οι συγκρίσεις σας είναι δαπανηρές, τότε ΜΟ3 κάνει περισσότερα συγκρίσεις από την επιλογή (μία μόνο τιμή περιστροφής) τυχαία. εγγραφές της βάσης δεδομένων μπορεί να είναι δαπανηρή για να συγκρίνετε.


Ενημέρωση: Το τράβηγμα σχόλια σε απάντηση.

mdkess υποστήριξε:

«Η διάμεση 3» ΔΕΝ είναι η πρώτη τελευταίο μέση. Επιλέξτε τρία τυχαία ευρετήρια, και να λάβει τη μέση τιμή του αυτή. Το όλο θέμα είναι να βεβαιωθείτε ότι η επιλογή σας άξονες δεν είναι ντετερμινιστική - αν είναι, χειρότερη περίπτωση που τα δεδομένα μπορούν να παραχθούν αρκετά εύκολα.

Στην οποία απάντησε:

  • Ανάλυση του αλγορίθμου εύρεσης Hoare του με διάμεση-Of-Three Partition (1997) από Ρ Kirschenhofer, Η Prodinger, C Martínez υποστηρίζει τον ισχυρισμό σας (η 'μέση-of-τρία' είναι τρία τυχαία σημεία).

  • Υπάρχει ένα άρθρο που περιγράφεται στο portal.acm.org που είναι σχετικά 'Η χειρότερη περίπτωση μεταθέσεων για Median-of-τρία Quicksort' από τον Hannu Erkiö, που δημοσιεύθηκε στον υπολογιστή Journal, Vol 27, No 3, 1984. [Update 2012-02- 26: Πήρε το κείμενο για το άρθρο . Τμήμα 2 «Ο αλγόριθμος» αρχίζει: « Χρησιμοποιώντας το διάμεσο των πρώτων, μεσαία και τελευταία στοιχεία του Α [L: R], αποδοτικό χωρίσματα σε τμήματα της αρκετά ίσης μεγεθών μπορεί να επιτευχθεί στις περισσότερες πρακτικές καταστάσεις. «Έτσι, συζητά την προσέγγιση πρώτης μέσης τελευταία ΜΟ3.]

  • Άλλο ένα σύντομο άρθρο που έχει ενδιαφέρον είναι η MD McIlroy, με τίτλο «Killer αντίπαλος για Quicksort» , που δημοσιεύτηκε στο λογισμικό, πρακτικών και εμπειριών, Vol. 29 (0), 1-4 (0 1999). Εξηγεί πώς να κάνει σχεδόν κάθε Quicksort συμπεριφέρονται τετραγώνου.

  • AT & T Bell Labs Tech Journal, Οκτώβριος 1984 «Θεωρία και Πράξη για την κατασκευή μιας εργασίας Ταξινόμηση ρουτίνας» δηλώνει «Hoare πρότεινε στεγανοποίηση γύρω από τη μέση αρκετών τυχαία επιλεγμένων γραμμών. Sedgewick [...] συνιστάται η επιλογή του διάμεσου της πρώτης [. ..] τελευταία [...] και μεσαία». Αυτό δείχνει ότι και οι δύο τεχνικές για «διάμεσο-of-τρία» γνωστές στην βιβλιογραφία. (Ενημέρωση 23/11/2014: Το άρθρο αυτό φαίνεται να είναι διαθέσιμη στο IEEE Xplore ή από Wiley - εάν έχετε μελών ή είναι διατεθειμένοι να καταβάλλουν ένα τέλος.)

  • «Μηχανική μια Λειτουργία Ταξινόμηση» από τον JL Bentley και MD McIlroy, που δημοσιεύθηκε στο Software πρακτικής και εμπειρίας, Τόμος 23 (11), Νοέμβριος 1993, πηγαίνει σε μια εκτεταμένη συζήτηση των θεμάτων, και επέλεξαν ένα προσαρμοστικό αλγόριθμο διαχωρισμού βασίζεται εν μέρει για την το μέγεθος του συνόλου δεδομένων. Υπάρχει πολλή συζήτηση για συμβιβασμούς για διάφορες προσεγγίσεις.

  • Μια αναζήτηση στο Google για «μέση-of-τρία» λειτουργεί αρκετά καλά για περαιτέρω παρακολούθηση.

Ευχαριστώ για τις πληροφορίες; Είχα αντιμετώπισε μόνο το ντετερμινιστική «μέση-of-τρία» πριν.

Απαντήθηκε 02/10/2008 στις 20:42
πηγή χρήστη

ψήφοι
1

Αν διαλογή μία τυχαία προσπελάσιμη από τη συλλογή (όπως μια σειρά), είναι γενικά καλύτερο για να πάρει τη φυσική μέση στοιχείο. Με αυτό, αν η σειρά είναι όλα έτοιμα ταξινόμηση (ή σχεδόν ταξινομημένο), οι δύο χωρίσματα θα είναι κοντά ακόμα, και θα πάρετε την καλύτερη ταχύτητα.

Αν διαλογή κάτι με μόνο γραμμικά πρόσβασης (όπως μια συνδεδεμένη λίστα), τότε είναι καλύτερα να επιλέξετε το πρώτο στοιχείο, επειδή είναι ο πιο γρήγορος σημείο πρόσβασης. Εδώ, όμως, αν η λίστα έχει ήδη ταξινομηθεί, είστε βιδώνονται - ένα διαμέρισμα θα είναι πάντα μηδενική, και η άλλη έχει τα πάντα, παράγει την χειρότερη στιγμή.

Ωστόσο, για μια συνδεδεμένη λίστα, να πάρει τίποτα εκτός από την πρώτη, θα κάνει μόνο τα πράγματα χειρότερα. Θα πάρει το μεσαίο στοιχείο σε ένα διατηρητέο ​​λίστα, θα πρέπει να εντείνουν μέσα από αυτό σε κάθε βήμα διαμέρισμα - προσθήκη O (/ 2 N) λειτουργία που γίνεται logN φορές κάνοντας συνολικό χρόνο O (1,5 N * log N) και αυτό είναι αν γνωρίζουμε πόσο καιρό η λίστα είναι πριν ξεκινήσετε - συνήθως εμείς δεν γι 'αυτό θα πρέπει να το βήμα σε όλη τη διαδρομή μέχρι τα μετρήσω, τότε το βήμα μισά του δρόμου μέσω της για να βρει τη μέση, τότε το βήμα μέσα από μια τρίτη φορά να κάνει την πραγματική διαμέρισμα: O (2,5 Ν * log N)

Απαντήθηκε 02/10/2008 στις 20:42
πηγή χρήστη

ψήφοι
1

Εξαρτάται αποκλειστικά από το πώς τα δεδομένα σας είναι ταξινομημένο για να αρχίσει με. Αν νομίζετε ότι θα είναι ψευδο-τυχαία, στη συνέχεια, το καλύτερο στοίχημά σας είναι είτε να πάρει μια τυχαία επιλογή ή να επιλέξετε τη μέση.

Απαντήθηκε 02/10/2008 στις 20:46
πηγή χρήστη

ψήφοι
16

Heh, μου δίδαξε μόνο αυτή την κατηγορία.

Υπάρχουν αρκετές επιλογές.
Απλό: Διαλέξτε το πρώτο ή το τελευταίο στοιχείο της σειράς. (κακή σε μερικώς ταξινομημένη εισόδου) Καλύτερη: Διαλέξτε το στοιχείο στο μέσον του εύρους. (καλύτερα σε μερικώς ταξινομημένο εισόδου)

Ωστόσο, επιλέγοντας οποιοδήποτε αυθαίρετο στοιχείο διατρέχει τον κίνδυνο της κακώς στεγανοποίηση της συστοιχίας μεγέθους n σε δύο συστοιχίες μεγέθους 1 και η-1. Αν το κάνετε αρκεί το γεγονός ότι συχνά, quicksort σας διατρέχει τον κίνδυνο να γίνει O (n ^ 2).

Μια βελτίωση που έχω δει είναι να επιλέξετε μέση (πρώτη, τελευταία, μέσα)? Στη χειρότερη περίπτωση, μπορεί ακόμα να πάει σε O (n ^ 2), αλλά πιθανολογικά, αυτό είναι μια σπάνια περίπτωση.

Για τα περισσότερα στοιχεία, να πάρει το πρώτο ή το τελευταίο είναι επαρκής. Αλλά, αν διαπιστώσετε ότι τρέχετε σε χειρότερη περίπτωση σενάρια συχνά (μερικώς ταξινομημένο εισόδου), η πρώτη επιλογή θα ήταν να πάρει το κεντρικό αξία (η οποία είναι μια στατιστικά καλό περιστροφής για μερική ταξινομημένα δεδομένα).

Αν είστε ακόμα τρέχει σε προβλήματα, τότε πάει η μέση οδός.

Απαντήθηκε 02/10/2008 στις 20:46
πηγή χρήστη

ψήφοι
8

Ποτέ μην επιλέξετε ποτέ ένα σταθερό άξονα - αυτό μπορεί να επιτεθεί για να εκμεταλλευτεί χειρότερη περίπτωση O αλγόριθμος σας (n ^ 2) runtime, το οποίο είναι μόνο για μπελάδες. χειρότερη περίπτωση χρόνου εκτέλεσης Quicksort του παρουσιάζεται όταν διχοτόμηση αποτελέσματα σε μία σειρά από 1 στοιχείου, και μία σειρά από n-1 στοιχεία. Ας υποθέσουμε ότι έχετε επιλέξει το πρώτο στοιχείο το διαμέρισμα σας. Αν κάποιος τροφοδοτεί μια σειρά για να αλγόριθμο σας που είναι σε φθίνουσα σειρά, η πρώτη σας άξονα θα είναι το μεγαλύτερο, οπότε ό, τι άλλο στη σειρά θα κινηθούν προς τα αριστερά του. Στη συνέχεια, όταν recurse, το πρώτο στοιχείο θα είναι η μεγαλύτερη και πάλι, έτσι για μια ακόμη φορά θα θέσει τα πάντα προς τα αριστερά του, και ούτω καθεξής.

Μια καλύτερη τεχνική είναι η μέθοδος μέση-της-3, όπου μπορείτε να επιλέξετε τρία στοιχεία στην τύχη, και να επιλέξετε τη μέση. Ξέρετε ότι το στοιχείο που θα επιλέξετε δεν θα είναι η πρώτη ή η τελευταία, αλλά και από το κεντρικό οριακό θεώρημα, η κατανομή της μέσης στοιχείο θα είναι κανονική, το οποίο σημαίνει ότι θα τείνουν προς τα μέσα (και ως εκ τούτου , n lg n ώρα).

Αν θέλετε οπωσδήποτε να εγγυηθεί O (nlgn) χρόνο εκτέλεσης του αλγορίθμου, η μέθοδος στήλες-of-5 για την εύρεση του διάμεσου ενός πίνακα τρέχει σε χρόνο O (n) χρόνο, πράγμα που σημαίνει ότι η εξίσωση επανάληψης για quicksort στη χειρότερη περίπτωση θα να T (n) = O (n) (δείτε το διάμεσο) + O (n) (partition) + 2Τ (n / 2) (recurse αριστερά και δεξιά.) από την κύρια μονάδα θεώρημα, αυτό είναι O (n lg n) . Ωστόσο, ο σταθερός συντελεστής θα είναι τεράστια, και αν χειρότερη επίδοση περίπτωση είναι η κύρια ανησυχία σας, χρησιμοποιήστε μια συγχώνευση είδος αντ 'αυτού, το οποίο είναι μόνο λίγο πιο αργά από ό, τι quicksort κατά μέσο όρο, και εγγυάται O (nlgn) το χρόνο (και θα είναι πολύ πιο γρήγορα από αυτό το κουτσός διάμεση quicksort).

Επεξήγηση του Median της διάμεσες Αλγόριθμος

Απαντήθηκε 25/10/2008 στις 22:50
πηγή χρήστη

ψήφοι
5

Μην προσπαθήσετε και να πάρει πάρα πολύ έξυπνος και να συνδυάσουν τις στρατηγικές περιστροφής. Αν συνδυαστεί μέσο όρο 3 με τυχαία περιστροφής επιλέγοντας τη μέση της πρώτης, τελευταία και ένα τυχαίο δείκτη στη μέση, τότε θα εξακολουθεί να είναι ευάλωτη σε πολλές από τις διανομές που στέλνουν μέσο όρο των 3 τετραγωνική (τόσο στην πραγματικότητα χειρότερη από ό, τι του απλό τυχαίο άξονα)

Π.χ. μια κατανομή όργανο σωλήνων (1,2,3 ... Ν / 2..3,2,1) πρώτη και τελευταία δύο θα είναι 1 και η τυχαία δείκτης θα είναι κάποια αριθμός μεγαλύτερος από 1, λαμβάνοντας το διάμεσο δίνει 1 ( είτε πρώτη ή η τελευταία) και θα έχετε μια extermely ισορροπημένη στεγανοποίηση.

Απαντήθηκε 26/10/2008 στις 04:54
πηγή χρήστη

ψήφοι
1

Είναι πιο εύκολο να σπάσει το quicksort σε τρία τμήματα να γίνει αυτό

  1. λειτουργία Exchange ή το στοιχείο δεδομένων ανταλλαγής
  2. Η λειτουργία χώρισμα
  3. Επεξεργασία των χωρίσματα

Είναι μόνο λίγο περισσότερο inefficent από μία μακρά λειτουργία, αλλά είναι πολλά εύκολο να καταλάβει.

Κωδικός εξής:

/* This selects what the data type in the array to be sorted is */

#define DATATYPE long

/* This is the swap function .. your job is to swap data in x & y .. how depends on
data type .. the example works for normal numerical data types .. like long I chose
above */

void swap (DATATYPE *x, DATATYPE *y){  
  DATATYPE Temp;

  Temp = *x;        // Hold current x value
  *x = *y;          // Transfer y to x
  *y = Temp;        // Set y to the held old x value
};


/* This is the partition code */

int partition (DATATYPE list[], int l, int h){

  int i;
  int p;          // pivot element index
  int firsthigh;  // divider position for pivot element

  // Random pivot example shown for median   p = (l+h)/2 would be used
  p = l + (short)(rand() % (int)(h - l + 1)); // Random partition point

  swap(&list[p], &list[h]);                   // Swap the values
  firsthigh = l;                                  // Hold first high value
  for (i = l; i < h; i++)
    if(list[i] < list[h]) {                 // Value at i is less than h
      swap(&list[i], &list[firsthigh]);   // So swap the value
      firsthigh++;                        // Incement first high
    }
  swap(&list[h], &list[firsthigh]);           // Swap h and first high values
  return(firsthigh);                          // Return first high
};



/* Finally the body sort */

void quicksort(DATATYPE list[], int l, int h){

  int p;                                      // index of partition 
  if ((h - l) > 0) {
    p = partition(list, l, h);              // Partition list 
    quicksort(list, l, p - 1);        // Sort lower partion
    quicksort(list, p + 1, h);              // Sort upper partition
  };
};
Απαντήθηκε 10/03/2011 στις 03:19
πηγή χρήστη

ψήφοι
0

Στην ιδανική περίπτωση ο άξονας θα πρέπει να είναι η μέση τιμή στο σύνολο του πίνακα. Αυτό θα μειώσει τις πιθανότητες να πάρει χειρότερη επίδοση περίπτωση.

Απαντήθηκε 17/04/2013 στις 15:57
πηγή χρήστη

ψήφοι
-1

Σε μια πραγματικά βελτιστοποιημένη εφαρμογή, η μέθοδος για την επιλογή περιστροφής πρέπει να εξαρτάται από το μέγεθος του πίνακα - για μια μεγάλη σειρά, πληρώνει μακριά για να περνούν περισσότερο χρόνο επιλέγοντας μια καλή άξονα. Χωρίς να κάνει μια πλήρη ανάλυση, θα ήθελα να μαντέψει «μέση O (log (n)) στοιχεία» είναι μια καλή αρχή, και αυτό έχει το πρόσθετο πλεονέκτημα ότι δεν απαιτεί καμία επιπλέον μνήμη: Χρησιμοποιώντας την ουρά-κλήση στο μεγαλύτερο διαμέρισμα και IN- μέρος στεγανοποίηση, χρησιμοποιούμε το ίδιο O (log (n)) επιπλέον μνήμη σε σχεδόν κάθε στάδιο του αλγορίθμου.

Απαντήθηκε 08/10/2013 στις 20:50
πηγή χρήστη

ψήφοι
0

πολυπλοκότητα Γρήγορη είδους ποικίλλει σε μεγάλο βαθμό με την επιλογή της αξίας άξονα. Για παράδειγμα, αν επιλέξετε πάντα πρώτο στοιχείο ως pivot, πολυπλοκότητα αλγορίθμου γίνεται τόσο χειρότερο το O (n ^ 2). εδώ είναι μια έξυπνη μέθοδο για να επιλέξετε άξονα στοιχείο- 1. επιλέξει το πρώτο, τα μέσα, το τελευταίο στοιχείο του πίνακα. 2. συγκρίνει αυτές τις τρεις αριθμούς και να βρείτε τον αριθμό που είναι μεγαλύτερος από ένα και μικρότερο από ό, τι άλλες, δηλαδή μέση. 3. κάνουν αυτό το στοιχείο ως στοιχείο άξονα.

επιλογή του στροφέα με τη μέθοδο αυτή χωρίζει τη συστοιχία σε σχεδόν δύο ήμισυ και ως εκ τούτου η πολυπλοκότητα μειώνει σε O (nlog (n)).

Απαντήθηκε 05/12/2013 στις 06:05
πηγή χρήστη

ψήφοι
0

Κατά μέσο όρο, διάμεση τιμή των 3 είναι καλό για μικρά n. Διάμεση τιμή των 5 είναι λίγο καλύτερα για μεγαλύτερες n. Η ninther, η οποία είναι η «διάμεσος των τριών διάμεσοι των τριών» είναι ακόμα καλύτερη για πολύ μεγάλες n.

Η υψηλότερη πάτε με δειγματοληψία το καλύτερο που μπορείτε να πάρετε ως n αυξάνεται, αλλά η βελτίωση επιβραδύνει δραματικά προς τα κάτω, όπως σας αυξήσει τα δείγματα. Και θα προκύψουν, η επιβάρυνση της δειγματοληψίας και διαλογής δείγματα.

Απαντήθηκε 19/10/2016 στις 10:04
πηγή χρήστη

ψήφοι
0

Θα ήθελα να συστήσω χρησιμοποιώντας το μεσαίο δείκτη, όπως μπορεί εύκολα να υπολογιστεί.

Μπορείτε να υπολογίσετε με στρογγυλοποίηση (array.length / 2).

Απαντήθηκε 09/08/2017 στις 01:29
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more