Skip to content

Commit 1a2cd34

Browse files
committed
希尔排序
1 parent eb789e8 commit 1a2cd34

File tree

17 files changed

+100283
-65
lines changed

17 files changed

+100283
-65
lines changed

bubble/bubble_test.go

Lines changed: 0 additions & 21 deletions
This file was deleted.

insertion/insertion_test.go

Lines changed: 0 additions & 21 deletions
This file was deleted.

selection/selection_test.go

Lines changed: 0 additions & 22 deletions
This file was deleted.

sort/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
排序:
2+
将多个元素按照一定规则的顺序进行排列。
3+
4+
如:
5+
数值排序
6+
字母排序
7+
优先级排序
8+
9+
分析:
10+
排序则必有先后大小高低,基本操作是:将元素通过比较来调整位置。
11+
12+
排序本质是消除逆序。采用“交换相邻元素”的办法来消除逆序,每次正好只消除一个,因此必须执行O(N^2)的交换次数。
13+
基于交换元素的排序要想突破这个下界,必须执行一些比较,交换相隔比较远的元素,使得一次交换能消除一个以上的逆序。这样才能降低时间复杂度。
File renamed without changes.

sort/bubble/bubble_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package bubble
2+
3+
import (
4+
"github.com/stretchr/testify/assert"
5+
"testing"
6+
"github.com/xiaomeng79/go-algorithm/sort/testdata"
7+
"github.com/xiaomeng79/go-algorithm/sort/utils"
8+
)
9+
10+
11+
func TestBubbleSort(t *testing.T) {
12+
for _, v := range testdata.Values {
13+
assert.Exactly(t, v.Sort, BubbleSort(v.Nosort), "no eq")
14+
}
15+
}
16+
17+
func benchmarkBubbleSort(n int,b *testing.B) {
18+
b.StopTimer()
19+
list := utils.GetArrayOfSize(n)
20+
b.ReportAllocs()
21+
b.StartTimer()
22+
for i:=0;i < b.N;i++ {
23+
BubbleSort(list)
24+
}
25+
}
26+
27+
func BenchmarkBubbleSort100(b *testing.B) { benchmarkBubbleSort(100, b) }
28+
func BenchmarkBubbleSort1000(b *testing.B) { benchmarkBubbleSort(1000, b) }
29+
func BenchmarkBubbleSort10000(b *testing.B) { benchmarkBubbleSort(10000, b) }
30+
func BenchmarkBubbleSort100000(b *testing.B) { benchmarkBubbleSort(100000, b) }

insertion/insertion.go renamed to sort/insertion/insertion.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,20 @@ func InsertionSort(arr []int) []int {
2222
}
2323
return arr
2424
}
25+
26+
func InsertionSort2(arr []int) []int {
27+
length := len(arr)
28+
//if length == 1 {return arr}
29+
30+
for i := 1; i < length; i++ {
31+
backup := arr[i]
32+
j := i -1;
33+
//将选出的被排数比较后插入左边有序区
34+
for j >= 0 && backup < arr[j] {//注意j >= 0必须在前边,否则会数组越界
35+
arr[j+1] = arr[j]//移动有序数组
36+
j -- //反向移动下标
37+
}
38+
arr[j + 1] = backup //插队插入移动后的空位
39+
}
40+
return arr
41+
}

sort/insertion/insertion_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package insertion
2+
3+
import (
4+
"github.com/stretchr/testify/assert"
5+
"testing"
6+
"github.com/xiaomeng79/go-algorithm/sort/testdata"
7+
"github.com/xiaomeng79/go-algorithm/sort/utils"
8+
)
9+
10+
11+
func TestInsertionSort(t *testing.T) {
12+
for _, v := range testdata.Values {
13+
assert.Exactly(t, v.Sort, InsertionSort(v.Nosort), "no eq")
14+
}
15+
}
16+
17+
func benchmarkInsertionSort(n int,b *testing.B) {
18+
b.StopTimer()
19+
list := utils.GetArrayOfSize(n)
20+
b.ReportAllocs()
21+
b.StartTimer()
22+
for i:=0;i < b.N;i++ {
23+
InsertionSort(list)
24+
}
25+
}
26+
27+
func BenchmarkInsertionSort100(b *testing.B) { benchmarkInsertionSort(100, b) }
28+
func BenchmarkInsertionSort1000(b *testing.B) { benchmarkInsertionSort(1000, b) }
29+
func BenchmarkInsertionSort10000(b *testing.B) { benchmarkInsertionSort(10000, b) }
30+
func BenchmarkInsertionSort100000(b *testing.B) { benchmarkInsertionSort(100000, b) }
31+
File renamed without changes.

sort/selection/selection_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package selection
2+
3+
import (
4+
"testing"
5+
"github.com/stretchr/testify/assert"
6+
"github.com/xiaomeng79/go-algorithm/sort/testdata"
7+
"github.com/xiaomeng79/go-algorithm/sort/utils"
8+
)
9+
10+
func TestSelectionSort(t *testing.T) {
11+
for _, v := range testdata.Values {
12+
assert.Exactly(t, v.Sort, SelectionSort(v.Nosort), "no eq")
13+
}
14+
}
15+
16+
17+
func benchmarkSelectionSort(n int,b *testing.B) {
18+
b.StopTimer()
19+
list := utils.GetArrayOfSize(n)
20+
b.ReportAllocs()
21+
b.StartTimer()
22+
for i:=0;i < b.N;i++ {
23+
SelectionSort(list)
24+
}
25+
}
26+
27+
28+
func BenchmarkSelectionSort100(b *testing.B) { benchmarkSelectionSort(100, b) }
29+
func BenchmarkSelectionSort1000(b *testing.B) { benchmarkSelectionSort(1000, b) }
30+
func BenchmarkSelectionSort10000(b *testing.B) { benchmarkSelectionSort(10000, b) }
31+
func BenchmarkSelectionSort100000(b *testing.B) { benchmarkSelectionSort(100000, b) }
32+

sort/shell/shell.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//希尔排序
2+
package shell
3+
4+
//原理:也称递减增量排序算法,先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
5+
//稳定性:不稳定
6+
//比较: 1万以内用插入排序,以上使用希尔排序
7+
//算法步骤:
8+
//1. 选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;
9+
//2. 按增量序列个数 k,对序列进行 k 趟排序;
10+
//3. 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
11+
12+
func ShellSort(arr []int) []int{
13+
length := len(arr)
14+
//设置增量
15+
gap := length/2
16+
//结束条件,增量为<=0
17+
for gap > 0 {
18+
//根据增量,进行分组插入排序
19+
for i:=0;i<gap;i++ {
20+
insertsort(arr,i,gap)
21+
}
22+
//分组完,组排序后,重新设置增量
23+
gap /= 2
24+
}
25+
return arr
26+
}
27+
28+
func insertsort(arr []int,start,gap int) {
29+
length := len(arr)
30+
for i:=start +gap;i<length;i+=gap {
31+
preindex := i-gap
32+
cur := arr[i]
33+
for preindex >= 0 && cur < arr[preindex] {
34+
arr[preindex + gap] = arr[preindex]
35+
preindex -= gap
36+
}
37+
arr[preindex + gap] = cur
38+
}
39+
}
40+

sort/shell/shell_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package shell
2+
3+
import (
4+
"testing"
5+
"github.com/stretchr/testify/assert"
6+
"github.com/xiaomeng79/go-algorithm/sort/testdata"
7+
"github.com/xiaomeng79/go-algorithm/sort/utils"
8+
)
9+
10+
func TestShell(t *testing.T) {
11+
for _, v := range testdata.Values {
12+
assert.Exactly(t, v.Sort, ShellSort(v.Nosort), "no eq")
13+
}
14+
}
15+
16+
17+
func benchmarkShellSort(n int,b *testing.B) {
18+
b.StopTimer()
19+
list := utils.GetArrayOfSize(n)
20+
b.ReportAllocs()
21+
b.StartTimer()
22+
for i:=0;i < b.N;i++ {
23+
ShellSort(list)
24+
}
25+
}
26+
27+
func BenchmarkShellSort100(b *testing.B) { benchmarkShellSort(100, b) }
28+
func BenchmarkShellSort1000(b *testing.B) { benchmarkShellSort(1000, b) }
29+
func BenchmarkShellSort10000(b *testing.B) { benchmarkShellSort(10000, b) }
30+
func BenchmarkShellSort100000(b *testing.B) { benchmarkShellSort(100000, b) }

testdata/sortdata.go renamed to sort/testdata/sortdata.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,4 @@ var (
99
{[]int{3}, []int{3}},
1010
{[]int{3, -1, -6, 34, -78}, []int{-78, -6, -1, 3, 34}},
1111
}
12-
Value = []int{3, 44, 56, 38, 77, 38, 26}
1312
)

sort/utils/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#### 生成随机数

sort/utils/helper.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package utils
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"bufio"
7+
"strconv"
8+
)
9+
10+
const (
11+
File_Name = "../utils/intarray.txt"
12+
Num_Vol = 100000
13+
)
14+
15+
//获取文件绝对路径
16+
func absPath() string {
17+
_fpath,err := filepath.Abs(File_Name)
18+
if err != nil{
19+
panic(err)
20+
}
21+
return _fpath
22+
}
23+
24+
//判断随机数文件是否存在
25+
func pathExists() bool {
26+
_fpath := absPath()
27+
_,err := os.Stat(_fpath)
28+
if os.IsNotExist(err) {
29+
return false
30+
}
31+
return true
32+
}
33+
//生成随机数文件
34+
func gen() {
35+
_fpath := absPath()
36+
GenRandFile(Num_Vol,_fpath)
37+
}
38+
39+
//获取随机数
40+
func GetArrayOfSize(n int) []int {
41+
_fpath := absPath()
42+
//判断文件是否存在
43+
if !pathExists() {
44+
gen()//不存在创建
45+
}
46+
//存在读取
47+
f ,err := os.Open(_fpath)
48+
if err != nil {
49+
panic(err)
50+
}
51+
defer f.Close()
52+
numbers := make([]int,n)
53+
scanner := bufio.NewScanner(f)
54+
55+
for i:=0;i<n;i++ {
56+
scanner.Scan()
57+
s,_ := strconv.Atoi(scanner.Text())
58+
numbers = append(numbers,s)
59+
}
60+
return numbers
61+
}
62+

0 commit comments

Comments
 (0)