排序算法
排序算法总结
注:本文中部分图解和思路参考博主dreamcatcher-cx:http://www.cnblogs.com/chengxiao/

选择排序
void selectSort(int *a, int len)
{
if (nullptr == a)
return;
int min;
int index;
for (int i = 0; i < len - 1; i++){
//当前最小值与最小值对应的索引号
min = a[i];
index = i;
for (int j = i + 1; j < len; j++)
if (a[j] < min)
{
min = a[j];
index = j;
}
//选出最小值,与a[i]交换
int temp = a[i];
a[i] = a[index];
a[index] = temp;
}
}
冒泡排序

void bubbleSort(int *a, int len)
{
if (nullptr == a)
return;
for (int i = 0; i < len; i++){
for (int j = 0; j < len - 1; j++){
//冒泡过程
//相邻两个数进行比较,较大的数向后移位,如此循len次
if (a[j] > a[j + 1]){
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}
插入排序

void insertSort(int *a, int len)
{
if (nullptr == a)
return;
for (int i = 1; i < len; i++){
int j = i;
while (j > 0 && a[j] < a[j-1])
{
int temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
j--;
}
}
}
快速排序

//核心思想:选择一个key,通过遍历数组使得key左侧的数小于key,右侧的值大于key.然后分别对key的左侧和右侧进行快排
/*
1、选择最右侧的值为key,left=0;right=N-1;
2、从left向右走,直到找到大于key的数,使a[right]=a[left].
3、从right向前遍历,直到找到小于key的数,使a[left]=a[right].
4、重复2、3过程直到left与right相遇。
*/
int partSort(int *a, int left, int right)
{
if (nullptr == a)
return 0;
int key = a[right];
while (left < right)
{
while (left < right && a[left] <= key)
left++;
a[right] = a[left];
while (left < right && a[right] >= key)
right--;
a[left] = a[right];
}
a[right] = key;
return right;
}
void quickSort(int *a, int left, int right)
{
if (nullptr == a)
return;
if (left >= right)
return;
int index = partSort(a, left, right);
quickSort(a, left, index - 1);
quickSort(a, index + 1, right);
}
归并排序

void mergeArray(int *arr, int l, int r, int *temp)
{
//std::cout << "left:" << l << " " << "right:" << r << std::endl;
if (l >= r)
return;
int mid = (l + r) / 2;
mergeArray(arr, l, mid, temp);
mergeArray(arr, mid + 1, r, temp);
int *aux = new int[r - l + 1]; //这里弄一个要处理的数组副本 长度是 R-L+1
for (int i = l; i <= r; i++) //副本数组从 L 开始,所以与原数组存在一个 L 的偏移量
aux[i - l] = arr[i];
int i = l, j = mid + 1; //i记录左边元素的下标位置 j记录右边元素的下标位置
for (int k = l; k <= r; k++){ //k记录 arr 的下标位置
if (i >mid){
arr[k] = aux[j - l];
j++;
}
else if (j >r){
arr[k] = aux[i - l];
i++;
}
else if (aux[i - l] < aux[j - l]){
arr[k] = aux[i - l];
i++;
}
else{
arr[k] = aux[j - l];
j++;
}
}
}
void mergeSort(int *a, int len)
{
if (nullptr == a)
return;
int *p = new int[len];
if (nullptr == p)
return;
mergeArray(a, 0, len - 1, p);
delete[] p;
}
堆排序
- 将无序数组构建成大顶堆
- 将堆顶元素与末尾元素交换
- 重新调整堆,使其仍为大顶堆,反复执行交换和调整的步骤
void adjustHeap(int* arr, int i, int len){
if (NULL == arr)
return;
int temp = arr[i];
for (int k = 2 * i + 1; k < len; k = 2 * k + 1){
if (k + 1 < len && arr[k] < arr[k + 1]){//左子节点小于右子节点
k++;
}
if (arr[k] > temp){
swap(arr[i], arr[k]);
i = k;
}
else{
break;
}
}
}
void heapSort(int* arr, int len){
if (NULL == arr)
return;
//1.构建大顶堆
for (int i = len / 2 - 1; i >= 0; i--){//从最后一个非叶子节点开始
//调整大顶堆
adjustHeap(arr, i, len);
}
//2.调整堆结构,交换堆顶元素与末尾元素
for (int j = len - 1; j > 0; j--){
swap(arr[0], arr[j]);
//重新调整堆
adjustHeap(arr, 0, j);
}
}

浙公网安备 33010602011771号