nlogn的排序:堆排,快排,归并
堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
void adjustHeap(int a[], int i, int size)
{
//int max;
int l = 2 * i + 1;
int r = 2 * i + 2;
int max = i;
//vs 2017 会检测&&右边的,故不能将l < size&& a[l] > a[max]书写
if (l < size) {
if ( a[l] > a[max])
max = l;
}
if (r < size) {
if ( a[r] > a[max])
max = r;
}
if (max != i)
{
::std::swap(a[i], a[max]);
adjustHeap(a, max, size);
}
}
void heapSort(int a[],int size)
{
for (int i = size / 2 - 1; i >=0; i--)
{
adjustHeap(a, i, size);
}
for (int i = size-1;i >= 0; i--)
{
swap(a[0], a[i]);
adjustHeap(a, 0, i);
}
}
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
void bubbleSort(int a[], int size)
{
for (int i = 0; i < size - 1; i++)
{
for (int j = 0; j < size - i - 1; j++)
{
if (a[j] > a[j + 1])
::std::swap(a[j + 1], a[j]);
}
}
}
快速排序(Quicksort):通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序(Quicksort)是对冒泡排序的一种改进。
int quickSortPart(int a[],int left,int right)
{
int temp = a[right];
while (left<right)
{
while (left<right&&a[left]<temp )
{
left++;
}
a[right] = a[left];
while (left < right&&a[right] >=temp)
{
right--;
}
a[left] = a[right];
}
a[right] = temp;
return right;
}
void quickSort(int a[], int left, int right)
{
if (left<right)
{
int mid = quickSortPart(a, left, right);
quickSort(a, left, mid - 1);
quickSort(a, mid + 1, right);
}
}
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
void MergeData(int* arr, int left, int mid, int right, int* tmp) {
int index = left;
int p = left, q = mid; // 双指针遍历
// 待排区间===[left , right)
// 左有序区间[left, mid) 右有序区间[mid, right)
while (p < mid && q < right) {
if (arr[p] <= arr[q]) {
tmp[index++] = arr[p++];
}
else {
tmp[index++] = arr[q++];
}
}
while (p < mid) {
tmp[index++] = arr[p++];
}
while (q < right) {
tmp[index++] = arr[q++];
}
for (int i = left; i < right; i++) {
// [left, right)内的数列已全部有序
arr[i] = tmp[i];
}
}
void _MergeSort(int* arr, int left, int right, int* tmp) {
if (right - left > 1) {
int mid = left + ((right - left) >> 1);
// 1.排左区间
_MergeSort(arr, left, mid, tmp);
// 2.排右区间
_MergeSort(arr, mid, right, tmp);
// 3.归并
MergeData(arr, left, mid, right, tmp);
}
}
void MergeSort(int* arr, int size) {
int* tmp = (int*)malloc(sizeof(int) * size);
if (tmp == NULL) {
cout<<"error"<<endl;
return;
}
_MergeSort(arr, 0, size, tmp);
free(tmp);
}