01 - 冒泡排序
void bubbleSort(int *arr, int len)
{
if(NULL == arr || len < 2)
{
return;
}
int i,j;
for(i = 0; i < len; i++)
{
for(j = len - 1 - i; j >= 0; j--)
{
if(arr[j-1] > arr[j])
{
int tmp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = tmp;
}
}
}
}
02 - 鸡尾酒排序
void cockTailSort(int *arr, int len)
{
if(NULL == arr || len < 2)
{
return;
}
int left = 0;
int right = len - 1;
int i = 0;
while(left < right)
{
for(i = left; i < right; i++)
{
if(arr[i] > arr[i+1])
{
int tmp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = tmp;
}
}
right--;
for(i = right; i > left; i--)
{
if(arr[i] < arr[i-1])
{
int tmp = arr[i];
arr[i] = arr[i-1];
arr[i-1] = tmp;
}
}
left++;
}
}
03 - 选择排序
/* 选择排序:
* 从需要排序的队列数据中选择最小的值同第一个值交换,
* 再从剩下的部分中选择最下的与第二个交换,
* 最后实现全队列的排序
*/
void selectSort(int *arr, int len)
{
if(NULL == arr || len < 2)
{
return;
}
int idx, value, i, j;
for(i = 0; i < len; i++)
{
idx = i;
value =arr[i];
for(j = i+1; j < len; j++)
{
if(arr[j] < value)
{
value = arr[j];
idx = j;
}
}
arr[idx] = arr[i];
arr[i] = value;
}
}
04 - 插入排序
/* 直接插入排序:
* 把n个待排序的元素看成一个有序表和一个无序表。
* 开始时,有序表中只包含一个元素,无序表中包含n-1个元素。
* 排序过程中每次从无序表中取出一个元素,
* 将它插到有序表中的适当位置,使之成为新的有序表。
* 重复n-1次即可完
*/
void insertSort(int *arr, int len)
{
if(NULL == arr || len < 2)
{
return;
}
int i, j, lastSortedElement;
for(i = 1; i < len; i++)
{
lastSortedElement = arr[i];
for(j = i - 1; j >= 0 && arr[j] > lastSortedElement; j--)
{
arr[j+1] = arr[j];
}
arr[j+1] = lastSortedElement;
}
}
05 - 折半排序算法
/* 折半插入排序:
* 是直接插入排序的升级版本,使用折半查找算法减少关键字的比较次数
*/
void binary_insertionSort(int *arr, int len)
{
if(NULL == arr || len < 2)
{
return;
}
int i, j, left, mid, right, lastSortedElement;
for(i = 1; i < len; i++)
{
lastSortedElement = arr[i];
left = 0;
right = i - 1;
while(left <= right)
{
mid = (left + right) / 2;
if(arr[mid] > lastSortedElement)
{
right = mid -1;
}
else
{
left = mid + 1;
}
}
for(j = i -1; j >= left; j--)
{
arr[j+1] = arr[j];
}
arr[left] = lastSortedElement;
}
}
06 - 希尔排序
/* 希尔排序(缩小增量排序)
* 首先将较大的数据集合分割成若干个小组,
* 然后对每一个小组分别进行插入排序。
* 此时,插入排序所作用的数据量比较小,插入的效率比较高。
* */
void shellSort(int *arr, int len)
{
if(NULL == arr || len < 2)
{
return;
}
int i, j, maxValue, increment;
for(increment = len/2; increment >0; increment/=2)
{
for(i = increment; i < len; i++)
{
maxValue = arr[i];
for(j = i - increment; j >= 0 && maxValue < arr[j]; j -= increment)
{
arr[j + increment] = arr[j];
}
arr[j + increment] = maxValue;
}
}
}
07 - 堆排序
/* 堆排序:
* 将待排序序列构造成一个大顶堆(父节点比子节点大, 即arr[i] >= arr[2*i+1] && arr[i] >= arr[2*i + 2]),
* 此时,整个序列的最大值就是堆顶的根节点。
* 将其与末尾元素进行交换,此时末尾就为最大值。
* 然后将剩余n-1个元素重新构成一个堆,这样会得到n个元素的次小值。
* 如此反复执行,便能得到一个有序序列。
*/
void heapAdjust(int *arr, int i, int len)
{
if(NULL == arr || i < 0 || len < 0)
{
return;
}
int child;
for(; 2 * i + 1 < len; i = child)
{
// i是父节点的下表, 2*i+1是左子节点,2*i+2是右子节点
child = 2 * i +1;
// 选中两个子节点中较大的值
if(child < len-1 && arr[child + 1] > arr[child])
{
++child;
}
// 比较父节点和子节点中的较大值
if(arr[i] < arr[child])
{
int tmp = arr[i];
arr[i] = arr[child];
arr[child] = tmp;
}
}
}
void heapSort(int *arr, int len)
{
if(NULL == arr || len < 0)
{
return;
}
// 构建大顶堆
int i;
for(i = len/2-1; i >= 0; --i)
{
heapAdjust(arr, i, len);
}
// 调整堆结构,交换堆顶元素和末尾元素
for(i = len - 1; i > 0; --i)
{
// 将堆顶元素与末尾元素进行交换
int tmp = arr[0];
arr[0] = arr[i];
arr[i] = tmp;
// 重新对堆进行调整
heapAdjust(arr, 0, i);
}
}
08 - 归并排序
/* 归并排序:
* 将数据进行两两分组,每组之间进行排序。
* 每个小组排序完后,再将这些有序的小组与有序的小组间进行合并排序, 直到最后合并完。
*/
void merge(int *arr, int head, int mid, int tail)
{
int i,
left = mid - head + 1,
right = tail - mid,
arrLeft[left + 1],
arrRight[right+1];
for(i = 0; i < left; i++)
{
arrLeft[i] = arr[head + i];
}
for(i = 0; i < right; i++)
{
arrRight[i] = arr[mid + i + 1];
}
arrLeft[left] = INT_MAX;
arrRight[right] = INT_MAX;
left = 0;
right = 0;
for(i = 0; i < tail - head + 1; i++)
{
if(arrLeft[left] < arrRight[right])
{
arr[head + i] = arrLeft[left];
left++;
}
else
{
arr[head + i] = arrRight[right];
right++;
}
}
}
void mergeSortRecursion(int *arr, int left, int right)
{
int mid = (left + right)/2;
if(left < right)
{
mergeSortRecursion(arr, left, mid);
mergeSortRecursion(arr, mid+1, right);
merge(arr, left, mid, right);
}
}
void mergeSortIteration(int *arr, int left, int right)
{
int low, mid, high, size;
for(size = 1; size <= right - left; size *= 2)
{
low = left;
while(low + size - 1 <= right - 1)
{
mid = low + size - 1;
high = mid + size;
if(high > right)
{
high = right;
}
merge(arr, low, mid, high);
low = high + 1;
}
}
}
09 - 快速排序
/* 快速排序:
* 先从数列中读取一个数作为基准数
* 然后将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边
* 再对左右区间重复第二步,直到各区间只有一个数
*/
int partitation(int *arr, int left, int right)
{
int i,
tail = left - 1,
pivot = arr[right];
for(i = left; i < right; i++)
{
if(arr[i] <= pivot)
{
tail++;
int tmp = arr[tail];
arr[tail] = arr[i];
arr[i] = tmp;
}
}
int tmp = arr[tail+1];
arr[tail+1] = arr[right];
arr[right] = tmp;
return tail + 1;
}
void quickSort(int *arr, int left, int right)
{
int pivotIndex;
if(left < right)
{
pivotIndex = partitation(arr, left, right);
quickSort(arr, left, pivotIndex-1);
quickSort(arr, pivotIndex + 1, right);
}
}
以上, 完成。