# 算法学习笔记：排序算法(二)

william

## 希尔排序

``````function shellSort(arr) {
var n = arr.length
for (var gap = parseInt(n/2); gap > 0; gap=parseInt(gap/2)) {
for (var i=gap; i<arr.length; i++) {
var j = i - gap, temp = arr[i]
while (arr[j] > temp) {
arr[j+gap] = arr[j]
j = j - gap
}
arr[j+gap] = temp
}
}
console.log(arr)
}
shellSort([3,44,38,5,47,15,36,26,27,2,46,4,19,50,48])``````

``````function shellSort(arr) {
var n = arr.length, gap = 1
while (gap < n / 3) {
gap = gap * 3 + 1
}
for (gap; gap > 0; gap=parseInt(gap/3)) {
for (var i=gap; i<arr.length; i++) {
for (var j = i - gap;j >= 0; j-=gap) {
if (arr[j] > arr[j+gap]) {
var temp = arr[j+gap]
arr[j+gap] = arr[j]
arr[j] = temp
}
}
}
}
console.log(arr)
}
shellSort([3,44,38,5,47,15,36,26,27,2,46,4,19,50,48])``````

## 分治法

1. 把该问题缩小到一定规模就可以容易解决
2. 该问题可以被分解为若干个规模较小的相同问题
3. 利用该问题的子问题的解向上合并可以得到该问题的解
4. 该问题分解出的子问题是相互独立的

## 归并排序

### 自顶向下的归并排序

``````function sort(arr) {
var n = arr.length
if (n < 2) return arr
var mid = Math.ceil(n / 2)
var left = arr.slice(0, mid)
var right = arr.slice(mid)
return merge(sort(left), sort(right));
}

function merge(left, right){
var result = []
while (left.length && right.length) {
if (left[0] < right[0]) {
result.push(left.shift())
} else {
result.push(right.shift())
}
}
while (left.length) {
result.push(left.shift())
}
while (right.length) {
result.push(right.shift())
}
return result;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(sort(arr))``````

### 自底向上的归并排序

``````function merge(arr, start, mid, end){
var i = start, j= mid + 1, copy = []
for (var k = start; k <= end; k++) {
copy[k] = arr[k]
}
for (var k = start; k <= end; k++) {
if (i > mid) { // 左边取完取右边的元素
arr[k] = copy[j]
j++
} else if (j > end) { // 右边取完取左边的元素
arr[k] = copy[i]
i++
} else if (copy[j] < copy[i]) { // 右边的元素小于左边的元素，取右边的元素
arr[k] = copy[j]
j++
} else { // 左边的元素小于右边的元素，取左边的元素
arr[k] = copy[i]
i++
}
}
console.log(arr)
}

function sort(arr) {
var n = arr.length
for (var i = 1; i < n; i = i + i) { // i子数组的大小
for (var j = 0; j < n - i; j = j + i + i) { // j数组的索引
var start = j
var end = Math.min(j + i + i - 1, n-1)
var mid = parseInt((start + end) / 2)
merge(arr, start, mid, end)
}
}
}

var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
sort(arr)``````

## 快速排序

``````function sort(arr, left, right) {
var temp = arr[left],i = left, j = right, t;
if (left < right) {
while (i != j) {
while (arr[j] >= temp && i < j) {
j--
}
while (arr[i] <= temp && i < j) {
i++
}
if (i < j) {
t = arr[i]
arr[i] = arr[j]
arr[j] = t
}
}
arr[left] = arr[i]
arr[i] = temp
sort(arr, left, i - 1)
sort(arr, i + 1, right)
}
return arr
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(sort(arr, 0, arr.length - 1))``````

``````function sort(arr, left, right) {
var temp = arr[left],i = left, j = right,k = left + 1, t;
if (left < right) {
while (k <= j) {
if (arr[k] < temp) {
t = arr[k]
arr[k] = arr[i]
arr[i] = t
i++;
k++;
} else if (arr[k] > temp) {
t = arr[k]
arr[k] = arr[j]
arr[j] = t
j--;
} else {
k++;
}
}
sort(arr, left, i - 1)
sort(arr, j + 1, right)
}
return arr
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48,44,38];
console.log(sort(arr, 0, arr.length - 1))``````

love and share

2.6k 声望
824 粉丝
0 条评论