github.com/benz9527/toy-box/algo@v0.0.0-20240221120937-66c0c6bd5abd/sort/quick.go (about)

     1  package sort
     2  
     3  import (
     4  	"math/rand"
     5  	"time"
     6  )
     7  
     8  func swap(arr []int, i int, j int) {
     9  	temp := arr[i]
    10  	arr[i] = arr[j]
    11  	arr[j] = temp
    12  }
    13  
    14  func equalPartition(arr []int, l int, r int) (int, int) {
    15  	less := l - 1
    16  	more := r
    17  	pivot := arr[r]
    18  
    19  	for more > l {
    20  		if arr[l] < pivot {
    21  			less++
    22  			if l != less {
    23  				swap(arr, l, less)
    24  			}
    25  			l++
    26  		} else if arr[l] > pivot {
    27  			more--
    28  			if l != more {
    29  				swap(arr, l, more)
    30  			}
    31  		} else {
    32  			l++
    33  		}
    34  	}
    35  
    36  	if more != r {
    37  		swap(arr, more, r)
    38  	}
    39  	return less + 1, more - 1
    40  }
    41  
    42  func quickSort(arr []int, l int, r int) {
    43  	if r > l {
    44  		swap(arr, r, l+rand.Intn(r-l+1))
    45  		loc1, loc2 := equalPartition(arr, l, r)
    46  		quickSort(arr, l, loc1-1)
    47  		quickSort(arr, loc2+1, r)
    48  	}
    49  }
    50  
    51  func QuickSort(arr []int) {
    52  	n := len(arr)
    53  	if arr == nil || n < 2 {
    54  		return
    55  	}
    56  	rand.Seed(time.Now().UnixNano())
    57  	quickSort(arr, 0, n-1)
    58  }
    59  
    60  /*  another implementation  */
    61  func partition(arr []int, low int, high int) int {
    62  	// choose the rightmost element as pivot
    63  	pivot := arr[high]
    64  
    65  	// pointer for greater element
    66  	i := low - 1
    67  
    68  	// traverse through all elements and compare each element with pivot
    69  	for j := low; j < high; j++ {
    70  		if arr[j] <= pivot {
    71  			// if element smaller than pivot is found swap it with the greater element pointed by i
    72  			i++
    73  
    74  			// swapping element at i with element at j
    75  			temp := arr[i]
    76  			arr[i] = arr[j]
    77  			arr[j] = temp
    78  		}
    79  	}
    80  
    81  	// swap the pivot element with the greater element specified by i
    82  	temp := arr[i+1]
    83  	arr[i+1] = arr[high]
    84  	arr[high] = temp
    85  
    86  	// return the position from where partition is done
    87  	return i + 1
    88  }
    89  
    90  func quickSort2(arr []int, low int, high int) {
    91  	if low < high {
    92  		// find pivot element such that
    93  		// elements smaller than pivot are on the left
    94  		// elements greater that pivot are on the right
    95  		pi := partition(arr, low, high)
    96  
    97  		quickSort2(arr, low, pi-1)
    98  		quickSort2(arr, pi+1, high)
    99  	}
   100  }
   101  
   102  func QuickSort2(arr []int) {
   103  	n := len(arr)
   104  	if arr == nil || n < 2 {
   105  		return
   106  	}
   107  	quickSort2(arr, 0, n-1)
   108  }