快速排序qsort()源码及使用实例。
来源:互联网 发布:手机淘宝彩票在哪里 编辑:程序博客网 时间:2024/05/19 12:29
qsort()是最有效的快排序法之一。其函数原型是viod qsort(void *base, size_t_nmemb, size_t_size, int (*compar)( const void *), const void *);第一个参数为指向要排序的数组头部的指针。第二个参数为需要排序的项目数量。因为qsort()将第一个参数转换为void指针,所以会失去每个数组元素大小的信息,为了补充该信息,需要将数组大小告诉qsort()。第三个参数是一个指向函数的指针,被指向的函数用于确定排序顺序。这个比较函数应该接受两个参数,即分别指向进行比较的两个项目的指针。以下是调用qsort()函数的函数实例。/*qsorter.c 使用qsort()对一组数字排序*/#include <stdio.h>#include <stdlib.h>#define NUM 40void fillarray (double ar[], int n);void showarray (const double ar[], int n);int mycopy(const void *p1, const void *p2);int main (void){double vals[NUM];fillarray(vals,NUM);puts("Random list:");showarray(vals, NUM);qsort(vals,NUM,sizeof (double),mycopy);puts("\nSorted list:");showarray(vals,NUM);return 0;}void fillarray (double ar[], int n){int index;for (index = 0; index < n; index ++){ar[index] = (double)rand()/((double)rand()+0.1);}}void showarray (const double ar[], int n){int index;for (index = 0; index < n; index ++){printf ("%9.4f",ar[index])if (index & 6 == 5)putchar('\n');}if (index % 6 != 0)putchar('\n');}int mycopy (const void *p1, const void *p2){const double *a1 = (const double *) p1;const double *a2 = (const double *) p2;if (*a1 < *a2)return -1;else if (*a1 == *a2)return 0;elsereturn 1;}----------------------------------------------------------------以下是搜索到的qsort()函数源码---------------------------------------------------------<pre id="best-content-281179165" class="best-text mb-10">void __fileDECL qsort ( void *base, size_t num, size_t width, int (__fileDECL *comp)(const void *, const void *) )#endif /* __USE_CONTEXT */{ char *lo, *hi; /* ends of sub-array currently sorting */ char *mid; /* points to middle of subarray */ char *loguy, *higuy; /* traveling pointers for partition step */ size_t size; /* size of the sub-array */ char *lostk[STKSIZ], *histk[STKSIZ]; int stkptr; /* stack for saving sub-array to be processed */ /* validation section */ _VALIDATE_RETURN_VOID(base != NULL || num == 0, EINVAL); _VALIDATE_RETURN_VOID(width > 0, EINVAL); _VALIDATE_RETURN_VOID(comp != NULL, EINVAL); if (num < 2) return; /* nothing to do */ stkptr = 0; /* initialize stack */ lo = (char *)base; hi = (char *)base + width * (num-1); /* initialize limits */ /* this entry point is for pseudo-recursion calling: setting lo and hi and jumping to here is like recursion, but stkptr is preserved, locals aren't, so we preserve stuff on the stack */recurse: size = (hi - lo) / width + 1; /* number of el's to sort */ /* below a certain size, it is faster to use a O(n^2) sorting method */ if (size <= CUTOFF) { __SHORTSORT(lo, hi, width, comp, context); } else { /* First we pick a partitioning element. The efficiency of the algorithm demands that we find one that is approximately the median of the values, but also that we select one fast. We choose the median of the first, middle, and last elements, to avoid bad performance in the face of already sorted data, or data that is made up of multiple sorted runs appended together. Testing shows that a median-of-three algorithm provides better performance than simply picking the middle element for the latter case. */ mid = lo + (size / 2) * width; /* find middle element */ /* Sort the first, middle, last elements into order */ if (__COMPARE(context, lo, mid) > 0) { swap(lo, mid, width); } if (__COMPARE(context, lo, hi) > 0) { swap(lo, hi, width); } if (__COMPARE(context, mid, hi) > 0) { swap(mid, hi, width); } /* We now wish to partition the array into three pieces, one consisting of elements <= partition element, one of elements equal to the partition element, and one of elements > than it. This is done below; comments indicate conditions established at every step. */ loguy = lo; higuy = hi; /* Note that higuy decreases and loguy increases on every iteration, so loop must terminate. */ for (;;) { /* lo <= loguy < hi, lo < higuy <= hi, A[i] <= A[mid] for lo <= i <= loguy, A[i] > A[mid] for higuy <= i < hi, A[hi] >= A[mid] */ /* The doubled loop is to avoid calling comp(mid,mid), since some existing comparison funcs don't work when passed the same value for both pointers. */ if (mid > loguy) { do { loguy += width; } while (loguy < mid && __COMPARE(context, loguy, mid) <= 0); } if (mid <= loguy) { do { loguy += width; } while (loguy <= hi && __COMPARE(context, loguy, mid) <= 0); } /* lo < loguy <= hi+1, A[i] <= A[mid] for lo <= i < loguy, either loguy > hi or A[loguy] > A[mid] */ do { higuy -= width; } while (higuy > mid && __COMPARE(context, higuy, mid) > 0); /* lo <= higuy < hi, A[i] > A[mid] for higuy < i < hi, either higuy == lo or A[higuy] <= A[mid] */ if (higuy < loguy) break; /* if loguy > hi or higuy == lo, then we would have exited, so A[loguy] > A[mid], A[higuy] <= A[mid], loguy <= hi, higuy > lo */ swap(loguy, higuy, width); /* If the partition element was moved, follow it. Only need to check for mid == higuy, since before the swap, A[loguy] > A[mid] implies loguy != mid. */ if (mid == higuy) mid = loguy; /* A[loguy] <= A[mid], A[higuy] > A[mid]; so condition at top of loop is re-established */ } /* A[i] <= A[mid] for lo <= i < loguy, A[i] > A[mid] for higuy < i < hi, A[hi] >= A[mid] higuy < loguy implying: higuy == loguy-1 or higuy == hi - 1, loguy == hi + 1, A[hi] == A[mid] */ /* Find adjacent elements equal to the partition element. The doubled loop is to avoid calling comp(mid,mid), since some existing comparison funcs don't work when passed the same value for both pointers. */ higuy += width; if (mid < higuy) { do { higuy -= width; } while (higuy > mid && __COMPARE(context, higuy, mid) == 0); } if (mid >= higuy) { do { higuy -= width; } while (higuy > lo && __COMPARE(context, higuy, mid) == 0); } /* OK, now we have the following: higuy < loguy lo <= higuy <= hi A[i] <= A[mid] for lo <= i <= higuy A[i] == A[mid] for higuy < i < loguy A[i] > A[mid] for loguy <= i < hi A[hi] >= A[mid] */ /* We've finished the partition, now we want to sort the subarrays [lo, higuy] and [loguy, hi]. We do the smaller one first to minimize stack usage. We only sort arrays of length 2 or more.*/ if ( higuy - lo >= hi - loguy ) { if (lo < higuy) { lostk[stkptr] = lo; histk[stkptr] = higuy; ++stkptr; } /* save big recursion for later */ if (loguy < hi) { lo = loguy; goto recurse; /* do small recursion */ } } else { if (loguy < hi) { lostk[stkptr] = loguy; histk[stkptr] = hi; ++stkptr; /* save big recursion for later */ } if (lo < higuy) { hi = higuy; goto recurse; /* do small recursion */ } } } /* We have sorted the array, except for any pending sorts on the stack. Check if there are any, and do them. */ --stkptr; if (stkptr >= 0) { lo = lostk[stkptr]; hi = histk[stkptr]; goto recurse; /* pop subarray from stack */ } else return; /* all subarrays done */}
0 0
- 快速排序qsort()源码及使用实例。
- 快速排序qsort算法实例
- 使用qsort实现快速排序
- 快速排序qsort的使用
- 使用qsort进行快速排序
- 二分法快速排序法 qsort C源码
- qsort 使用快速排序例程进行排序
- C语言下使用快速排序qsort
- 快速排序库函数qsort的使用
- C中qsort快速排序使用
- 快速排序qsort用法
- 快速排序 qsort
- 快速排序法qsort
- qsort快速排序
- qsort 快速排序
- 关于快速排序qsort
- qsort 快速排序法
- qsort 快速排序
- Swift学习笔记(二十八)——Switch-Case的高级用法
- form表单下载文件成功返回值得问题
- 让Keil同时支持C51和ARM的方法
- jsp的九大内置对象
- LeetCode Best Time to Buy and Sell Stock III
- 快速排序qsort()源码及使用实例。
- 欢迎使用CSDN-markdown编辑器
- boost ptree操作XML,方便又好用
- Rc与Box区别
- 数据结构-队列
- Android list 泛型 用Gson 转json字符串 出现 java.lang.StackOverflowError异常解决
- Andrew ng ML Coursera Quiz1
- 集成微信第三方登陆
- MyEclipse 强制杀掉后 INFO: Port busy 8009 java.net.BindException: Address already in use: JVM_Bind