-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
367 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
|
||
// 根据 80-20 原则(是指对某一数据集执行的80%的查找操作都是对其中20%的数据元素进行查找 | ||
// 自组织的方式最终会把这20%的数据位置置于数据集的起始位置 | ||
export function SeqSearch<T>(data: T[], elem:T):boolean { | ||
let len = data.length; | ||
for(let i=0;i<len; i++ ) { | ||
if(data[i] == elem) { | ||
if(i>len*0.2 && i>1) { | ||
let temp = data[i-1]; | ||
data[i-1] = data[i]; | ||
data[i] = temp; | ||
} | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
export function BinarySearch<T>(data: T[], elem:T):number { | ||
let start = 0; | ||
let end = data.length - 1; | ||
let mid = 0; | ||
|
||
while(start <= end) { | ||
mid = Math.floor((start+end)/2); | ||
if(elem > data[mid]) { | ||
start = mid + 1; | ||
} else if(elem < data[mid]) { | ||
end = mid - 1; | ||
} else { | ||
return mid; | ||
} | ||
} | ||
return -1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
|
||
import { Stack } from "./Stack"; | ||
|
||
function swap<T>(d: T[], index1: number, index2: number) { | ||
let temp = d[index1]; | ||
d[index1] = d[index2]; | ||
d[index2] = temp; | ||
} | ||
|
||
export function BubbleSort<T>(data: T[]) { | ||
let len = data.length; | ||
for (let i = 0; i < len - 1; i++) { | ||
for (let j = 0; j < len - 1; j++) { | ||
if (data[j] > data[j + 1]) { | ||
swap(data, j, j + 1); | ||
} | ||
} | ||
} | ||
} | ||
|
||
export function CombSort<T>(data: T[]) { | ||
let n = data.length; | ||
let j = n, | ||
s = 1.3, | ||
flag = false; | ||
while (j > 1 || flag) { | ||
let i = 0; | ||
j = Math.max(Math.floor(j / s), 1); | ||
flag = false; | ||
while (i + j < n) { | ||
if (data[i] > data[i + j]) { | ||
swap(data, i, i + j); | ||
flag = true; | ||
} | ||
i++; | ||
} | ||
} | ||
} | ||
|
||
export function SelectSort<T>(data: T[]) { | ||
let n = data.length; | ||
for (let i = 0; i < n - 1; i++) { | ||
let minIdx = i; | ||
for (let j = i + 1; j < n; j++) { | ||
if (data[minIdx] > data[j]) { | ||
minIdx = j; | ||
} | ||
} | ||
if (minIdx != i) { | ||
swap(data, i, minIdx); | ||
} | ||
} | ||
} | ||
|
||
export function InsertSort<T>(data: T[]) { | ||
let temp, inner; | ||
let n = data.length; | ||
for (let i = 1; i < n; i++) { | ||
temp = data[i]; | ||
inner = i; | ||
while (inner > 0 && data[inner - 1] >= temp) { | ||
data[inner] = data[inner - 1]; | ||
inner--; | ||
} | ||
data[inner] = temp; | ||
} | ||
} | ||
|
||
export function ShellSort<T>(data: T[]) { | ||
let n = data.length; | ||
let h = 1; | ||
while (h < n / 3) { | ||
h = 3 * h - 1; | ||
} | ||
while (h >= 1) { | ||
for (let i = h; i < n; i++) { | ||
for (let j = i; j >= h && data[j] < data[j - h]; j -= h) { | ||
swap(data, j, j - h); | ||
} | ||
} | ||
h = Math.ceil((h - 1) / 3); | ||
} | ||
} | ||
|
||
export function QuickSortRecursive<T>(data: T[]): T[] { | ||
return qsort(data); | ||
} | ||
function qsort<T>(d: T[]): T[] { | ||
if (d.length == 0) { | ||
return []; | ||
} | ||
let left = [], right = []; | ||
let pivot = d[0]; | ||
for (let i = 1; i < d.length; i++) { | ||
if (d[i] < pivot) { | ||
left.push(d[i]); | ||
} else { | ||
right.push(d[i]); | ||
} | ||
} | ||
return qsort(left).concat(pivot, qsort(right)); | ||
} | ||
|
||
// 严尉敏数据结构实现 | ||
function partion_v1<T>(d: T[], low: number, high: number): number { | ||
let pivotKey = d[low]; | ||
while (low < high) { | ||
while (high > low && d[high] >= pivotKey) { | ||
high--; | ||
} | ||
d[low] = d[high]; | ||
while (low < high && d[low] <= pivotKey) { | ||
low++; | ||
} | ||
d[high] = d[low]; | ||
} | ||
// now low == high | ||
d[low] = pivotKey; | ||
return low; | ||
} | ||
|
||
// 算法导论实现 | ||
function partion_v2<T>(d: T[], low: number, high: number): number { | ||
let pivotKey = d[high]; | ||
let p = low - 1; | ||
for (let j = low; j < high; j++) { | ||
if (d[j] <= pivotKey) { | ||
p++; | ||
if (p != j) { | ||
swap(d, p, j); | ||
} | ||
} | ||
} | ||
p += 1; | ||
swap(d, p, high); | ||
return p; | ||
} | ||
|
||
export function QuickSort<T>(data: T[]) { | ||
let s = new Stack<number>(); | ||
let low = 0, high = data.length - 1; | ||
if (low < high) { | ||
let p = partion_v2(data, low, high); | ||
if (p - 1 > low) { | ||
s.push(low); | ||
s.push(p - 1); | ||
} | ||
if (p + 1 < high) { | ||
s.push(p + 1); | ||
s.push(high); | ||
} | ||
while (!s.empty()) { | ||
let r = s.pop(); | ||
let l = s.pop(); | ||
p = partion_v2(data, l, r); | ||
if (p - 1 > l) { | ||
s.push(l); | ||
s.push(p - 1); | ||
} | ||
if (p + 1 < r) { | ||
s.push(p + 1); | ||
s.push(r); | ||
} | ||
} | ||
} | ||
} | ||
|
||
// 3 way quick sort | ||
function sort3way<T>(d: T[], low: number, high: number) { | ||
if (high <= low) { | ||
return; | ||
} | ||
let lt = low; | ||
let gt = high; | ||
let i = low + 1; | ||
let pivot = d[low]; | ||
while (i <= gt) { | ||
if (d[i] < pivot) { | ||
swap(d, i++, lt++); | ||
} else if (pivot < d[i]) { | ||
swap(d, i, gt--); | ||
} else { | ||
i++; | ||
} | ||
} | ||
|
||
sort3way(d, low, lt - 1); | ||
sort3way(d, gt + 1, high); | ||
} | ||
|
||
export function QuickSort3Way<T>(data: T[]) { | ||
sort3way(data, 0, data.length - 1); | ||
} | ||
|
||
// dual pivot | ||
function sortDualPiovt<T>(d: T[], low: number, high: number) { | ||
if (high <= low) { | ||
return; | ||
} | ||
|
||
let pivot1 = d[low]; | ||
let pivot2 = d[high]; | ||
if (pivot1 > pivot2) { | ||
swap(d, low, high); | ||
} else if (pivot1 == pivot2) { | ||
while (pivot1 == pivot2 && low < high) { | ||
low++; | ||
pivot1 = d[low]; | ||
} | ||
} | ||
|
||
let i = low + 1; | ||
let lt = low + 1; | ||
let gt = high - 1; | ||
while (i <= gt) { | ||
if (d[i] < pivot1) { | ||
swap(d, i++, lt++); | ||
} else if (d[i] > pivot2) { | ||
swap(d, i, gt--); | ||
} else { | ||
i++; | ||
} | ||
} | ||
swap(d, low, --lt); | ||
swap(d, high, ++gt); | ||
|
||
sortDualPiovt(d, low, lt - 1); | ||
sortDualPiovt(d, lt + 1, gt - 1); | ||
sortDualPiovt(d, gt + 1, high); | ||
} | ||
|
||
export function QuickSortDualPivot<T>(data: T[]) { | ||
sortDualPiovt(data, 0, data.length - 1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import {SeqSearch, BinarySearch} from "./Search"; | ||
import {QuickSort3Way} from "./Sort"; | ||
|
||
|
||
let d = [4,8,5,10,3,9,6,11,2]; | ||
QuickSort3Way(d); | ||
|
||
console.log(BinarySearch(d, 6)); | ||
|
||
console.log(BinarySearch(d, 1)); | ||
|
||
console.log(BinarySearch(d, 7)); | ||
|
||
console.log(BinarySearch(d, 12)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import * as sort from "./Sort"; | ||
import { deepcopy, print } from "./util"; | ||
|
||
|
||
function printSort<T>(d: T[], sortFunc: string) { | ||
let data = deepcopy(d); | ||
let ret; | ||
let start = new Date().getTime(); | ||
print(sortFunc," before sort: ", data); | ||
switch (sortFunc) { | ||
case "bubble": { | ||
sort.BubbleSort(data); | ||
break; | ||
} | ||
case "comb": { | ||
sort.CombSort(data); | ||
break; | ||
} | ||
case "select": { | ||
sort.SelectSort(data); | ||
break; | ||
} | ||
case "insert": { | ||
sort.InsertSort(data); | ||
break; | ||
} | ||
case "shell": { | ||
sort.ShellSort(data); | ||
break; | ||
} | ||
case "quick": { | ||
ret = sort.QuickSortRecursive(data); | ||
break; | ||
} | ||
case "quick-nr": { | ||
sort.QuickSort(data); | ||
break; | ||
} | ||
case "quick3way":{ | ||
sort.QuickSort3Way(data); | ||
break; | ||
} | ||
case "quickDualPivot": { | ||
sort.QuickSortDualPivot(data); | ||
break; | ||
} | ||
} | ||
print(sortFunc," after sort: ", !ret?data:ret); | ||
print(sortFunc," use times: ", new Date().getTime() - start, "ms"); | ||
} | ||
|
||
let d = [10,8,3,7,2,4,9,5,4,6]; | ||
|
||
printSort(d, "bubble"); | ||
printSort(d, "comb"); | ||
printSort(d, "select"); | ||
printSort(d, "insert"); | ||
printSort(d, "shell"); | ||
printSort(d, "quick-recursive"); | ||
printSort(d, "quick-nr"); | ||
printSort(d, "quick3way"); | ||
printSort(d, "quickDualPivot"); |
Oops, something went wrong.