-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsort.js
More file actions
305 lines (289 loc) · 6.9 KB
/
sort.js
File metadata and controls
305 lines (289 loc) · 6.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
/*
* 交换函数,交换数组中两个位置的数
*/
function swap(list,i,j) {
var temp = list[i];
list[i] = list[j];
list[j] = temp;
}
var mylist = [34,29,88,56,99,70,17,42,64];
console.log(mylist);
//插入排序:直接插入排序+希尔排序
//直接插入排序
function dinsert(list){
var len = list.length,key = null;
for(var i = 1;i < len;i++){
key = list[i];
for(var j = i-1;j >= 0;j--){
if(list[j] > key){
list[j+1] = list[j];
if(j == 0){
list[j] = key;
}
}else{
break;
}
}
list[j+1] = key;
}
return list;
}
//console.log("直接插入排序结果:" + dinsert(mylist));
//希尔排序
function shell(list){
if(list == null || list.length == 0) {
console.log("sort error!");
return list;
}
var len = list.length,temp = null,group = null;
for(group = Math.floor(list.length/2);group > 0;group = Math.floor(group/2)){
//增量的次数
for(var i = group; i < len;i++){
for(var j = i - group; j >= 0;j -= group){
if (list[j] > list[j + group]) {
temp = list[j];
list[j] = list[j + group];
list[j + group] = temp;
};
}
}
}
return list
}
/*
* 一趟希尔排序
*/
function shellInsert(list,dk) {
var i,j,len=list.length,key=null;
for(i = 0;i < len - dk;i++) {
// 将i+dk插入有序序列
if(list[i+dk] < list[i]) {
key = list[i+dk];
j = i + dk;
do{
// 记录后移
j -=dk;
list[j+dk] = list[j];
}while(j-dk > 0 && key < list[j-dk]);
list[j] = key;
}
}
}
function shell2(list) {
var group = null;
// group为增量,直到1的时候排序结束
for(group = Math.floor(list.length/2);group > 0; group = Math.floor(group/2)) {
shellInsert(list,group);
}
return list;
}
// console.log("希尔排序结果:" + shell(mylist));
//选择排序:直接选择排序+堆排序
//直接选择排序
function choose(list) {
var len = list.length,temp = null;
for (var i = 0; i < len; i++){
for(var j = i + 1;j < len;j++){
if(list[i] > list[j]) {
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
return list;
}
// console.log("直接选择排序结果:" + choose(mylist));
//堆排序
function buildMaxHeap(list,lastIndex) {
for(var i = Math.floor((lastIndex-1)/2);i >= 0;i--) {
// i为lastIndex的父节点
// k保存当前正在判断的节点
var k = i;
// 当k存在左节点时,即k存在子节点
while(2*k+1 <= lastIndex) {
// 暂时保存左节点的值到biggerIndex即最大值
var biggerIndex = 2*k+1;
if(biggerIndex < lastIndex) {
// 当左节点不是最后的节点的时候
// 判断左右节点哪个大,把大的序号保存到biggerIndex
if(list[biggerIndex] < list[biggerIndex+1]) {
biggerIndex++;
}
}
if(list[k] < list[biggerIndex]) {
// 比较父节点与左右节点最大值,把大值交换到父节点
// 交换后把k修改为biggerIndex,继续循环判断子节点
swap(list,k,biggerIndex);
k = biggerIndex;
}else {
break;
}
}
}
}
function heapSort(list){
var len = list.length;
for(var i = 0;i < len-1;i++) {
// 建堆,每次减去最后的数进行建堆
buildMaxHeap(list,len-1-i);
swap(list,0,len-1-i);
}
return list;
}
// console.log("堆排序:" + heapSort(mylist));
//交换排序:冒泡排序+快速排序
//冒泡排序
function bubbling(list) {
var len = list.length,temp;
// i表示本次冒泡参与的个数
for (var i = len - 1; i >= 0; i--) {
// j表示交换的次数
for (var j = 0;j < i;j++) {
if(list[j] > list[j+1]) {
temp = list[j];
list[j] = list[j+1];
list[j+1] = temp;
}
};
};
return list;
}
// console.log(bubbling(mylist));
//快速排序
function quick(list) {
// begin表示第一个数的序号,end表示最后一个数的序号
function sort(begin,end) {
var i = begin,
j = end,
// flag表示基准
flag = list[begin];
if(begin < end){
while(i < j) {
// 从后开始向前扫描,找到比基准小的数,放到list[i]
for (;i < j;j--) {
if(list[j] < flag) {
list[i++] = list[j];
break;
}
}
// 再从前向后扫描,找到比基准大的数,放到list[j]
for(;i < j;i++) {
if(list[i] > flag) {
list[j--] = list[i];
break;
}
}
}
// 最后i,j相同,所指向的位置就是flag的正确位置
list[i] = flag;
sort(0,i-1);
sort(i+1,end);
}
}
sort(0,list.length-1);
return list;
}
// 三数取中
function chooseMiddle(list,start,middle,end) {
// 最后为中,小,大;
if(list == null && list.length == 0) {
console.log("list error");
return 0;
}
var middleNum = list[start];
if(list[middle] > list[end]) {
swap(list,middle,end);
}
if(list[start] > list[end]) {
swap(list,start,end);
}
if(list[middle] > list[start]) {
swap(list,start,middle);
}
}
function quick2(list,start,end) {
var mid = Math.floor(((end-start+1)/2)+start);
chooseMiddle(list,start,mid,end);
var flag = list[start],
i = start,
j = end+1;
if(start < end){
while(i < j) {
// 从前向后找,找到比基准大的数
while(i < end && list[++i] <= flag);
// 从后向前找,找到比基准小的数
while(j > start && list[--j] >= flag);
// 交换两个数
if(i < j) {
swap(list,i,j);
}else {
break;
}
}
swap(list,start,j);
quick2(list,start,j);
quick2(list,j+1,end);
}
}
function quickSort2(list) {
quick2(list,0,list.length-1);
return list;
}
// console.log("快速排序:" + quick(mylist));
// console.log("快速排序2:" + quickSort2([6,4,6,7,1,6,7,6]));
console.log([6,4,0,2,6,8,7,1,6,7,6]);
console.log("快速排序3:" + quickSort3([6,4,0,2,6,8,7,1,6,7,6]));
// 归并排序
function merge(left,right){
var result = [];
while(left.length > 0 && right.length > 0) {
if (left[0] < right[0]) {
result.push(left.shift());
}else{
result.push(right.shift());
}
}
result = result.concat(left,right);
return result;
}
function mergeSort(list){
// 当数组只有一个元素的时候就返回该数组
if(list.length == 1) {
return list;
}
// 否则把数组分成左右两部分
var middle = Math.floor(list.length/2);
var left = list.slice(0,middle),
right = list.slice(middle);
// 对左右两边进行拆分后进行归并排序
return merge(mergeSort(left),mergeSort(right));
}
// console.log("归并排序:" + mergeSort(mylist));
/*
* 折半查找法
*/
function binarySearch(list,key,low,height) {
var mid = Math.floor((low+height)/2);
if (low > height) {
console.log('查找失败!');
return -1;
}
if(list[mid] == key) {
// 找到要查找的值
return mid;
}else if(list[mid] < key) {
// 所要查找的值比中间值大
low = mid + 1;
return binarySearch(list,key,low,height);
}else if(list[mid] > key) {
// 所要查找的值比中间值小
height = mid - 1;
return binarySearch(list,key,low,height);
}
}
function BinSearch(list,key) {
var result = null;
result = binarySearch(list,key,0,list.length-1);
console.log('查找结果:'+result);
}