排序算法的空间时间复杂度如下:
冒泡排序
S1:从待排序序列的末尾位置开始,从后往前依次比较各个位置和其后一位置的大小并执行S2。
S2:如果当前位置的值小于其前一位置的值,就把他俩的值交换(完成一次全序列比较后,序列最开始位置的值即此序列最小值,所以其不需要再参与冒泡)。
S3:将序列的第一个元素从待排序序列中移除。若移除后的待排序序列不为空则继续执行S1,否则冒泡结束。
class BubbleSort {
public:
int* bubbleSort(int* A, int n) {
// write code here
int temp;
for(int i = 0; i < n-1; i++){
for(int j = n-1; j > i; j--){
if(A[j]<A[j-1]){
temp = A[j];
A[j] = A[j-1];
A[j-1] = temp;
}
}
}
return A;
}
};
选择排序
选择排序的思路如下:
s1: 从待排序序列的首位开始,从前往后依次比较各个位置和其后一位置的大小,选出一个最小值。
s2:将该最小值与首位交换,将序列的首位指针向后移动一位,此时下次遍历的序列范围为 1~n-1,重复s1 。
s3:若序列的首位指针移动到序列的最后一位,排序结束
class SelectionSort {
public:
int* selectionSort(int* A, int n) {
// write code here
for(int i=0; i < n; i++){
int min = INT_MAX;//无限大
int index = 0;
for(int j = i; j < n; j++){
if(A[j]<min){
min= A[j];
index = j;
}
}
swap(A[i], A[index]);
}
return A;
}
};
插入排序
插入排序思路:
S1 首先将位置i上的数和前面的数进行比较,将小的数插入最前面
S2 i向后移动一位,重复s1,将i插入到前面有序数组的合适位置
S3 当i=n时,排序结束
class InsertionSort {
public:
int* insertionSort(int* A, int n) {
// write code here
for(int i=1;i<n;i++)//从第二个开始
{
int index=i;
for(int j=i-1;j>=0;j--){
if(A[index]<A[j]){
int temp=A[index];
A[index]=A[j];
A[j]=temp;
index=j;
}
}
}
return A;
}
};
归并排序
归并排序思路:
S1:现将数组归并为长度为1的有序区间
S2:将数组归并为长度为1x2的有序区间并进行排序
S3:将数组归并为长度为2x2=4的有序区间并排序
S4:当归并长度为数组长度时停止排序
class MergeSort {
public:
int* mergeSort(int* A, int n) {
// write code here
process(A, 0, n-1);
return A;
}
void process(int* A, int left, int right){
if(left == right) return;
int mid = (left+right)/2;
process(A, left, mid);
process(A, mid+1, right);
merge(A, left, mid, right);
}
//合并过程,分别将要合并的两个有序序列第一个元素进行比较,将最小的元素放入临时数组中
void merge(int* A, int left, int mid, int right){
int l = left;
int r = mid+1;
int temp[right-left+1];
int index = 0;
while(l<=mid&&r<=right){
if(A[l] <= A[r])
temp[index++] = A[l++];
else
temp[index++] = A[r++];
}
while(l<=mid)
temp[index++] = A[l++];
while(r<=right)
temp[index++] = A[r++];
for(int i = 0; i < index; i++)
A[left+i] = temp[i];
}
};
快速排序
算法思路:
S1:将序列的第一个值设为参考值,left指向数组第一个元素,right指向数组最后一个元素,具体排序步骤如下:
S2:使用递归的方法对整个数组进行分区,重复S1
S3:当left=right时结束排序
class QuickSort {
public:
void swap(int * A, int i, int j){
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
int partion(int* A, int left, int right){
int key = 0;
key = A[left];
while(left<right){
while((left<right) && (A[right] >= key)) right--;
swap(A, right, left);
while((left<right) && (A[left] <= key)) left++;
swap(A, left, right);
}
return left;
}
void sort(int* A, int left, int right){
int index = 0;
if(left >= right) return;
index = partion(A, left, right);
sort(A, left, index-1);
sort(A, index+1, right);
}
int* quickSort(int* A, int n) {
// write code here
sort(A, 0, n-1);
return A;
}
};
堆排序
实现堆排序算法之前,先看下树的基本概念:
查找数组中某个数的父结点和左右孩子结点,比如已知索引为i的数,那么
父结点索引:(i-1)/2(这里计算机中的除以2,省略掉小数)
左孩子索引:2i+1
右孩子索引:2i+2
堆排序算法主要是利用了一种堆的数据结构,具体的排序思路如下:
S1: 调整堆上的元素使其成为一个大根堆并输出堆顶元素,并将这个堆的最后一个元素与这个堆进行交换
S2: 输出堆顶元素,并将这个堆的最后一个元素放到数组末尾,重复S1。
S3:当堆中元素只有一个时停止排序。
class HeapSort {
public:
void swap(int* A, int i, int j){
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
void maxHeap(int* A, int root, int last){
int parent = root;
int largest = 2 * parent + 1;
while(largest <= last){
//如果右孩子存在并且大于左孩子
if(largest< last && A[largest] < A[largest +1]){
largest++;
}
//如果子节点大于父节点
if(A[largest] > A[parent]){
swap(A, largest, parent);
parent = largest;
//largest指向该节点的左节点
largest = 2 * parent + 1;
}
else break;
}
}
int* heapSort(int* A, int n) {
// write code here
if(A == NULL || n <=1) return A;
//创建初始大根堆
for(int i = n/2 + 1; i >= 0; i--){
maxHeap(A, i, n-1);
}
//交换根节点和最后一个节点
for(int i = n-1; i > 0; i--){
swap(A, 0, i);
maxHeap(A, 0, i-1);
}
return A;
}
};
希尔排序
希尔排序的具体思路如下:
选择一个初始步长gap一般为n/2
S1:隔gap个数取一个数,分为gap个组,对每个组进行直接插入排序
S2:将gap数量减半重复S1
S3:当gap为0时结束排序
class ShellSort {
public:
void swap(int *A, int i, int j){
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
void sort(int* A, int gap, int n){
for (int i = gap; i < n; i++){
int j = i - gap;
while(j>=0){
if(A[j] > A[j+gap]){
swap(A, j, j+gap);
}
j -= gap;
}
}
}
int* shellSort(int* A, int n) {
// write code here
if(n <= 1) return A;
int gap = n/2;
while(gap >= 1){
sort(A, gap, n);
gap = gap/2;
}
return A;
}
};