0%

数据结构常见排序方法

常见排序算法

冒泡排序

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
public class BubbleSort implements IArraySort {

@Override
public int[] sort(int[] sourceArray) throws Exception {
// 对 arr 进行拷贝,不改变参数内容
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

for (int i = 1; i < arr.length; i++) {
// 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。
// 这里这个标记点很关键
boolean flag = true;

for (int j = 0; j < arr.length - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr[j],arr[j+1]);
flag = false;
}
}
if (flag) {
break;
}
}
return arr;
}
}

堆排序

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
public void HeapSorts(int[] arr){
int n=arr.length;
buildHeap(arr, n);
int i;
for (i=n-1;i>=0;i—-){
swap(arr, i,0);
heapify(arr, i,0);
}
}
public void BuildHeap(int[] arr,n){
int last_node=n-1;
int parent =(last_node-1)/2;
int i;
for (i=parent; i>=0; i--){
heapify (tree, n, i);
}
}
public void heapify(int[] arr,int n ,int i){
//这里n表示数组的长度,i表示对第i节点做heapfy
if(i>n) return;
int C1=2*i+1; //子节点
int C2=2*i+2;
int max=i;
if (c1<n && arr[c1] > arr[max])//关键:这里要判断子节点存在
max=c1;
if (c2<n && arr[c2] > arr[max])
max=c2;
if(max !=i){
Swap(arr, max, i);
heapify(arr, n, max)//这里作递归
}

快排

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
//从数列中挑出一个元素,称为 “基准”(pivot);
//重新排序数列,比基准值小的放在前面,比基准值大的放在后面(相同的数可以到任一边)。
//在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
//递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
public class QuickSort implements IArraySort {
@Override
public int[] sort(int[] sourceArray) throws Exception {
// 对 arr 进行拷贝,不改变参数内容
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

return quickSort(arr, 0, arr.length - 1);
}

private int[] quickSort(int[] arr, int left, int right) {
if (left < right) {
int partitionIndex = partition(arr, left, right);
quickSort(arr, left, partitionIndex - 1);
quickSort(arr, partitionIndex + 1, right);
}
return arr;
}

private int partition(int[] arr, int left, int right) {
// 设定基准值(pivot)
int pivot = left;
int index = pivot + 1;
for (int i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) {
swap(arr, i, index);
index++;
}
}
swap(arr, pivot, index - 1);
return index - 1;
}

private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}

}

插入排序

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
public class InsertSort implements IArraySort {

@Override
public int[] sort(int[] sourceArray) throws Exception {
// 对 arr 进行拷贝,不改变参数内容
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

// 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
for (int i = 1; i < arr.length; i++) {

// 记录要插入的数据
int tmp = arr[i];

// 从已经排序的序列最右边的开始比较,找到比其小的数
int j = i;
while (j > 0 && tmp < arr[j - 1]) {
arr[j] = arr[j - 1];
j--;
}

// 存在比其小的数,插入
if (j != i) {
arr[j] = tmp;
}

}
return arr;
}
}

归并排序

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
int[] tmp;

public int[] sortArray(int[] nums) {
tmp = new int[nums.length];
mergeSort(nums, 0, nums.length - 1);
return nums;
}

public void mergeSort(int[] nums, int l, int r) {
if (l >= r) {
return;
}
int mid = (l + r) >> 1;
mergeSort(nums, l, mid);
mergeSort(nums, mid + 1, r);
int i = l, j = mid + 1;
int cnt = 0;
while (i <= mid && j <= r) {
if (nums[i] <= nums[j]) {
tmp[cnt++] = nums[i++];
} else {
tmp[cnt++] = nums[j++];
}
}
while (i <= mid) {
tmp[cnt++] = nums[i++];
}
while (j <= r) {
tmp[cnt++] = nums[j++];
}
for (int k = 0; k < r - l + 1; ++k) {
nums[k + l] = tmp[k];
}
}