#006# 快速排序 × 算法导论(第三版)练习 7.1-1 ~ 7.1-4

快排采用经典的分治思想,具体如下↓

分解:快排的核心步骤,其结果是数组被分成以某个数为基准的左右两个子数组(可能为空),其中左边的数都小于该基准数,右边的数都大于该基准数。详细步骤包括计算基准数下标,以及移动数组内元素。

解决:通过递归调用快速排序,对两个子数组进行排序。

合并:因为是原址排序,快速排序不需要合并操作。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <script type="text/javascript">
            function partition(arr, start, end) {
                let i = start;
                let j = end - 1;
                
                let x = arr[i];
                while (i < j) {
                    while (arr[j] >= x && i < j) j--;
                    arr[i] = arr[j];
                    while (arr[i] <= x && i < j) i++;
                    arr[j] = arr[i];
                }
                arr[i] = x;
                
                return i;
            }
                        
            function quicksort(arr, start, end) {
                if (start >= end - 1) { // 只有一个元素就不用排啦。
                    return;
                } else {
                    let mid = partition(arr, start, end); 
                    quicksort(arr, start, mid); 
                    quicksort(arr, mid + 1, end);
                }
            }

            function randomNum(min, max) {
                  let rg = max - min;
                  let rand = Math.random();
                  let digit = min + Math.floor(rand * rg); //舍去
                  return digit;
                  // min ≤ digit < max
            }
            
            function randomizedPartition(arr, start, end) {
                // 将首元素和随机元素交换
                let i = randomNum(start + 1, end);
                let temp = arr[i];
                arr[i] = arr[start];
                arr[start] = temp;        
                return partition(arr, start, end);
            }
            
            function randomizedQuicksort(arr, start, end) {
                if (start >= end - 1) { // 只有一个元素就不用排啦。
                    return;
                } else {
                    let mid = randomizedPartition(arr, start, end); 
                    randomizedQuicksort(arr, start, mid); 
                    randomizedQuicksort(arr, mid + 1, end);
                }                
            }
            
            let test_arr = [3, 3, 3, 3, 3, 3, 3];
            randomizedQuicksort(test_arr, 0, test_arr.length);
            console.log("", test_arr);
        </script>
    </body>
</html>
随机化版本(js描述)

7.1-1

挖坑填数,自行脑补~

7.1-2

输入规模为n,假设数组内元素都相同,则挖坑填数法的partition返回值依次为0,1,2,3,4,...,n-1,修改partition如下:

            function partition(arr, start, end) {
                // 数组元素全部相同的情况
                let k = start;
                for (; k != end - 1; ++k) {
                    if (arr[k] != arr[k + 1]) break;
                }
                if (k == end -1) {
                    return Math.floor((start + end) / 2)
                }
                
                let i = start;
                let j = end - 1;
                
                let x = arr[i];
                while (i < j) {
                    while (arr[j] >= x && i < j) j--;
                    arr[i] = arr[j];
                    while (arr[i] <= x && i < j) i++;
                    arr[j] = arr[i];
                }
                arr[i] = x;
                
                return i;
            }

7.1-3

i,j合作扫描了一遍数组,所以是theta n

7.1-4

partition里的>=和<=互换一下。

猜你喜欢

转载自www.cnblogs.com/xkxf/p/9789853.html
7.1