插入排序
//一.直接插入排序
void insertionSort(int *arr, int size)
{
//声明有序组最后一个元素 end, 无序组第一个元素 key
int end, key;
for (int i = 1; i < size; i++)
{
key = arr[i];
end = i - 1;
while (end >= 0 && key < arr[end])
{
arr[end + 1] = arr[end];
end--;
}
arr[end + 1] = key;
}
}
//一.(2)折半插入排序
void binaryInsertionSort(int *arr, int size)
{
int left, right, key, end;
for (int i = 1; i < size; i++)
{
left = 0; //有序数组第一个元素
right = i - 1; //有序数组最后一个元素
end = i - 1; //有序数组最后一个元素
key = arr[i];
while (left <= right)
{
int mid = left + (right - left) / 2;
if (key > arr[mid])
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
while (end >= left)
{
arr[end+1] = arr[end];
end--;
}
arr[end+1] = key;
}
}
//二.希尔排序
void shellSort(int *arr, int size)
{
//初始化增量
int gap = 1;
while (gap <= size/3)
{
gap = 3 * gap + 1;
}
//声明有序组最后一个元素 end, 无序组第一个元素 key
int end, key;
for (; gap > 0; gap = (gap - 1) / 3)
{
for (int i = gap; i < size; i += gap)
{
key = arr[i];
end = i - gap;
while (end >= 0 && key < arr[end])
{
arr[end + gap] = arr[end];
end = end - gap;
}
arr[end + gap] = key;
}
}
}
选择排序
//一.选择排序
void selectionSort(int *arr, int size)
{
int minIndex; //最小元素索引
for (int i = 0; i < size - 1; i++)//最后一个元素一定是最大(或最小),不需要排序
{
minIndex = i;
for (int j = i+1; j < size; j++)
{
if (arr[j] < arr[minIndex])
{
minIndex = j;
}
}
int tmp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = tmp;
}
}
//二.堆排序
void heapify(int *arr, int parent, int size)
{
#if 0
//递归版本
int lChild = 2 * parent + 1;
int rChild = 2 * parent + 2;
int currentMax = parent;
if (lChild < size && arr[lChild] > arr[currentMax])
{
currentMax = lChild;
}
if (rChild < size && arr[rChild] > arr[currentMax])
{
currentMax = rChild;
}
if (currentMax != parent)
{
swap(arr[parent], arr[currentMax]);
heapify(arr, currentMax, size);
}
#else
//非递归版本
for (int k = 2 * parent + 1; k < size; k = 2 * k + 1)
{
//让 k 指向孩子节点中最大的节点
if (k+1<size && arr[k] < arr[k+1])
{
k++;
}
if (arr[k] > arr[parent])
{
swap(arr[k], arr[parent]);
parent = k;
}
//孩子节点均小于父节点, 跳出循环
else
{
break;
}
}
#endif
}
void heapSort(int *arr, int size)
{
//从最后一个非叶子节点开始构建堆
for (int i = size / 2 - 1; i >= 0; i--)
{
heapify(arr, i, size);
}
//开始堆排序
for (int j = size - 1; j >= 0; j--)
{
swap(arr[0], arr[j]);
heapify(arr, 0, j);
}
}
交换排序
//一.冒泡排序
void bubbleSort(int *arr, int size)
{
for (int round = 0; round < size - 1; round++)
{
int flag = 0;
for (int i = 0; i < (size - 1) - round; i++)
{
if (arr[i] > arr[i + 1])
{
flag = 1;
int tmp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = tmp;
}
}
if (0 == flag)
{
break;
}
}
}
//二.快速排序
void quickSort(int *arr, int left, int right)
{
//递归跳出条件
if (left >= right)
{
return;
}
int lIndex = left;
int rIndex = right;
int baseValue = arr[left]; //设置基准值
//用基准值划分两部分
while (lIndex < rIndex)
{
while (arr[rIndex] >= baseValue && lIndex < rIndex)
{
rIndex--;
}
while (arr[lIndex] <= baseValue && lIndex < rIndex)
{
lIndex++;
}
if (lIndex < rIndex)
{
swap(arr[lIndex], arr[rIndex]);
}
}
//将基准值放置到 两部分 中间
arr[left] = arr[lIndex];
arr[lIndex] = baseValue;
quickSort(arr, left, lIndex - 1);
quickSort(arr, lIndex+1, right);
}
归并排序
//归并排序
void merge(int *arr, int left, int mid, int right);
void mergeSort(int *arr, int left, int right)
{
if (left >= right) //只有一个元素时返回,跳出递归
{
return;
}
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid+1, right);
merge(arr, left, mid, right);
}
void merge(int *arr, int left, int mid, int right)
{
//将数组arr看作两部分, 左半边为leftArr, 右半边为rightArr
int lLen = mid - left + 1;
int rLen = right - (mid + 1) + 1;
int *leftArr = new int[lLen];
int *rightArr = new int[rLen];
//向leftArr 和 rightArr 赋值
for (int i = 0; i < lLen; i++)
{
leftArr[i] = arr[left + i];
}
for (int i = 0; i < rLen; i++)
{
rightArr[i] = arr[mid + 1 + i];
}
//将leftArr 和 rightArr 中的元素比较重新排列到 arr 中
int lIndex = 0;
int rIndex = 0;
while (lLen != 0 && rLen != 0)
{
if (leftArr[lIndex] < rightArr[rIndex])
{
arr[left++] = leftArr[lIndex++];
lLen--;
}
else
{
arr[left++] = rightArr[rIndex++];
rLen--;
}
}
//将剩下元素插入 arr
if (lLen != 0)
{
while (lLen--)
{
arr[left++] = leftArr[lIndex++];
}
}
else
{
while (rLen--)
{
arr[left++] = rightArr[rIndex++];
}
}
delete[]leftArr;
delete[]rightArr;
}