void swap(int &a, int &b)
{
int tmp = a;
a = b;
b = tmp;
}
//不使用中间变量的swap函数
void swap_novar(int &a, int &b)
{
if (a != b)
{
a ^= b;
b ^= a;
a ^= b;
}
}
int Median3(int *a, int left, int right)
{
int center = (left + right)/2;
if(a[left] > a[center])
swap(a[left], a[center]);
if(a[left] > a[right])
swap(a[left], a[right]);
if(a[center] > a[right])
swap(a[center], a[right]);
swap(a[center], a[right-1]);
return a[right-1];
}
void Qsort1(int *a, int left, int right)
{
if(left >= right)
return;
int pivot = Median3(a, left, right);
int i = left, j = right-1;
while(1)
{
while(a[++i] < pivot);
while(a[--j] > pivot);
if(i < j)
swap(a[i], a[j]);
else
break;
}
swap(a[i], a[right-1]);
Qsort1(a, left, i-1);
Qsort1(a, i+1, right);
}
//快排算法实现2
void Qsort2(int *a, int left, int right)
{
if(left < right)
{
int pivot = a[left];
int i = left, j = right;
while(i < j)
{
while(i < j && a[j] >= pivot)
j--;
if(i < j)
a[i++] = a[j];
while(i < j && a[i] < pivot)
i++;
if(i < j)
a[j--] = a[i];
}
a[i] = pivot;
Qsort2(a, left, i-1);
Qsort2(a, i+1, right);
}
}
//堆排序
//堆向上调整,堆插入新元素时调用
//新插入元素在堆末尾,也就是下标为n-1处
//向上调整操作与堆排序无关
void MaxHeapFixUp(int a[], int n)
{
int i = n - 1;
int tmp = a[i];
int father = (i - 1)/2;
while(father >= 0 && i != 0)
{
if(a[father] > tmp)
break;
a[i] = a[father];
i = father;
father = (i - 1) / 2;
}
a[i] = tmp;
}
//最大堆向下调整,删除堆顶元素时调用(堆排序时使用)
void MaxHeapFixDown(int a[], int i, int n)
{
int tmp = a[i];
int lchild = 2*i + 1;
while(lchild < n)
{
if( (lchild+1) < n && a[lchild] < a[lchild + 1])
lchild++;
if(a[lchild] < tmp)
break;
a[i] = a[lchild];
i = lchild;
lchild = 2*i + 1;
}
a[i] = tmp;
}
//建最大堆
void MakeMaxHeap(int a[], int n)
{
int i;
for (i = n/2 - 1; i >= 0; i--)
MaxHeapFixDown(a, i, n);
}
//堆排序
void HeapSort(int a[], int n)
{
MakeMaxHeap(a, n);
int i = n-1;
for(i = n-1; i > 0; --i)
{
swap(a[0], a[i]);
MaxHeapFixDown(a, 0, i);
}
}
//冒泡排序
void BubbleSort(int a[], int n)
{
int i, j;
for(i = 0; i < n; i++)
{
for(j = 0; j < n-i; j++)
{
if(a[j] > a[j+1])
swap(a[j], a[j + 1]);
}
}
}
//添加标记flag,当序列已经全部有序后提前结束
void BubbleSort2(int a[], int n)
{
int flag = 1;
while(flag)
{
flag = 0;
for(int j = 0; j < n; j++)
{
if(a[j] > a[j+1])
{
swap(a[j], a[j + 1]);
flag = 1;
}
}
n--;
}
}
//直接插入排序(Insertion Sort):
//每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。
void InsertSort(int a[], int n)
{
int i = 0;
for(i = 1; i < n; i++)
{
int tmp = a[i];
int j = i - 1;
while(j >= 0 && a[j] > tmp)
{
a[j+1] = a[j];
j--;
}
a[j+1] = tmp;
}
}
//希尔排序:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
void ShellSort(int a[], int n)
{
int gap, i, j;
for(gap = n/2; gap > 0; gap /= 2)
{
for(i = 0; i < gap; i++)
{
for(j = i + gap; j < n; j += gap)
{
int tmp = a[j];
int k = j - gap;
while(k >= 0 && a[k] > tmp)
{
a[k + gap] = a[k];
k -= gap;
}
a[k + gap] = tmp;
}
}
}
}
//直接选择排序
void SelectSort(int a[], int n)
{
int i, j;
for(i = 0; i < n; ++i)
{
int min = a[i], k = i;
for(j = i + 1; j < n; j++)
{
if(a[j] < min)
{
min = a[j];
k = j;
}
}
swap(a[i], a[k]);
}
}
//归并排序
void merge(int a[], int tmparray[], int lpos, int rpos, int rightend)
{
int leftend = rpos - 1;
int tmppos = lpos;
int num = rightend - lpos + 1;
int i;
while(lpos <= leftend && rpos <= rightend)
{
if(a[lpos] < a[rpos])
tmparray[tmppos++] = a[lpos++];
else
tmparray[tmppos++] = a[rpos++];
}
while(lpos <= leftend)
tmparray[tmppos++] = a[lpos++];
while(rpos <= rightend)
tmparray[tmppos++] = a[rpos++];
for(i = 0; i < num; ++i, rightend--)
{
a[rightend] = tmparray[rightend];
}
}
void Msort(int a[], int tmparray[], int left, int right)
{
int mid;
if(left < right)
{
mid = (left + right)/2;
Msort(a, tmparray, left, mid);
Msort(a, tmparray, mid + 1, right);
merge(a, tmparray, left, mid + 1, right);
}
}
void MergeSort(int a[], int n)
{
int *tmparray = (int *)malloc(sizeof(int) * n);
if(tmparray != NULL)
{
Msort(a, tmparray, 0, n-1);
free(tmparray);
}
}
二分查找源码:
int binary_search(int array[], int n, int value)
{
int left = 0;
int right = n-1;
while(left <= right)
{
int mid = left + ((<span style="color:#ff0000;">unsigned int</span>(right - left))>>1); //凡是右移操作时,一定要考虑有符号数符号扩展的问题
if(array[mid] > value)
{
right = mid - 1;
}
else if(array[mid] < value)
{
left = mid + 1;
}
else
return mid;
}
return -1;
}