qsort函数定义如下
void qsort(void *base, // nums
size_t nitems, // sizeof(nums)/sizeof(nums[0])
size_t size, // sizeof(nums[0])
int (*compar)(const void *, const void *));
如果你要使用他,那么你大概需要自己写一个cmp函数,输出应该为-1,0,1来告知qsort怎么排序。(1:升序,-1:降序)
int cmp_int(const void*_a,const void*_b)
{
return *(int*)_a - *(int*)_b;
}
int cmp_char(const void*_a,const void*_b)
{
return *(char*)_a - *(char*)_b;
}
int cmp_dob(const void*_a,const void*_b)
{
return *(double*)_a > *(double*)_b ? 1 : -1;
}
// 或者一劳永逸版本
struct node{
int i;
double d;
char c;
};
int cmp(const void *a,const void *b) {
return (*(node*)a).i-(*(node*)b).i;
}
具体实例:
// nums:[1,1,1,3,3,4,3,2,4,2]->[1,1,1,2,2,3,3,3,4,4]
qsort(nums,NumSizes,sizeof(int),cmp_int);
C是没有自己的swap函数的,只能靠自己实现。
void swap(int *a,int *b)
{
a ^= b ^= a ^= b; //仅限int型
}
void swap1(int &a,int &b)
{
a = a + b;
b = a - b;
a = a - b;
}
void swap2(int &a,int &b) //创建临时变量,较为常用
{
int tmp = b;
b = a;
a = tmp;
}
常见的算法,小元素上浮,大元素下沉,当一次排序中没有交换时说明数组已经排序完全。
void bubble_sort(int *nums,int numsSize)
{
for(int i=0;i<numsSize;i++)
{
for(int j=numsSize-1;j>i;j--)
{
if(nums[j-1]>nums[j])
{
swap(nums[j-1],nums[j]);
}
}
}
}
逐个处理待排序的记录,每个记录与前面已排序已排序的子序列进行比较,将它插入子序列中正确位置。
void insert_sort(int *nums,int numsSize)
{
for(int i=0;i<numsSize;i++)
{
for(int j=i;j>1;j--)
{
if(nums[j-1]>nums[j])
{
swap(nums[j-1],nums[j]);
}
}
}
}
次从未排序的序列中找到最小元素,放到未排序数组的最前面。
void select_sort(int *nums,int numsSize)
{
for(int i=0;i<numsSize;i++)
{
for(int j=i+1;j<numsSize>;j++)
{
if(nums[i]>nums[j])
{
swap(nums[i],nums[j]);
}
}
}
}
这个推荐直接使用qsort,\(O(n\log{n})\)复杂度都不用自己手搓。
template<class Elem>
void mergesortcore(Elem A[],Elem temp[],int i,int j)
{
if(i == j) return;
int mid = (i + j)/2;
mergesortcore(A,temp,i,mid);
mergesortcore(A,temp,mid + 1,j);
/*归并*/
int i1 = i,i2 = mid + 1,curr = i;
while(i1 <= mid && i2 <= j){
if(A[i1] < A[i2])
temp[curr++] = A[i1++];
else
temp[curr++] = A[i2++];
}
while(i1 <= mid)
temp[curr++] = A[i1++];
while(i2 <= j)
temp[curr++] = A[i2++];
for(curr = i;curr <= j;curr++)
A[curr] = temp[curr];
}
template<class Elem>
void mergesort(Elem A[],int sz)
{
Elem *temp = new Elem[sz]();
int i = 0,j = sz - 1;
mergesortcore(A,temp,i,j);
delete [] temp;
}
/********************************************
* 向堆中插入元素
* hole:新元素所在的位置
********************************************/
template <class value>
void _push_heap(vector<value> &arr,int hole){
value v = arr[hole];//取出新元素,从而产生一个空洞
int parent = (hole - 1) / 2;
//建最大堆,如果建最小堆换成 arr[parent] > value
while(hole > 0 && arr[parent] < v){
arr[hole] = arr[parent];
hole = parent;
parent = (hole - 1) / 2;
}
arr[hole] = v;
}
/********************************************
* 删除堆顶元素
********************************************/
template <class value>
void _pop_heap(vector<value> &arr,int sz)
{
value v = arr[sz - 1];
arr[sz - 1] = arr[0];
--sz;
int hole = 0;
int child = 2 * (hole + 1); //右孩子
while(child < sz){
if(arr[child] < arr[child - 1])
--child;
arr[hole] = arr[child];
hole = child;
child = 2 * (hole + 1);
}
if(child == sz){
arr[hole] = arr[child - 1];
hole = child - 1;
}
arr[hole] = v;
_push_heap(arr,hole);
}
/********************************************
* 建堆
* sz:删除堆顶元素后的大小
* v: 被堆顶元素占据的位置原来的元素的值
********************************************/
template <class value>
void _make_heap(vector<value> &arr)
{
int sz = arr.size();
int parent = (sz - 2) / 2;
while(parent >= 0){
int hole = parent;
int child = 2 * (hole + 1); //右孩子
value v = arr[hole];
while(child < sz){
if(arr[child] < arr[child - 1])
--child;
arr[hole] = arr[child];
hole = child;
child = 2 * (hole + 1);
}
if(child == sz){
arr[hole] = arr[child - 1];
hole = child - 1;
}
arr[hole] = v;
_push_heap(arr,hole);
--parent;
}
}
template <class value>
void heap_sort(vector<value> &arr)
{
_make_heap(arr);
for(int sz = arr.size();sz > 1;sz--)
_pop_heap(arr,sz);
}