IndexSorter.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include "IndexSorter.h"
00025
00026 extern IndexSorter_Base
00027 IndexSorter_New(IndexSorter_Index lim, IndexSorter_Index empty) {
00028 IndexSorter_Base base = calloc(1, sizeof(struct IndexSorter_Struct));
00029 if (lim < 4) lim = 4;
00030 base->indexes = calloc(lim, sizeof(IndexSorter_Index));
00031 base->lim = lim;
00032 base->empty = empty;
00033 return base;
00034 }
00035
00036 extern void
00037 IndexSorter_Add(IndexSorter_Base base, IndexSorter_Index x) {
00038 if (base->sorter == NULL) return;
00039 IndexSorter_Index len = base->len;
00040 IndexSorter_Index *vec = base->indexes;
00041 if (len >= base->lim) {
00042
00043 IndexSorter_Index nLim = len + len/2 + 4;
00044 IndexSorter_Index *old = vec;
00045 vec = calloc(nLim, sizeof(IndexSorter_Index));
00046 base->indexes = vec;
00047 if (len > 0) memcpy(vec, old, len*sizeof(IndexSorter_Index));
00048 free(old);
00049 base->lim = nLim;
00050 }
00051 IndexSorter_Index son = len;
00052 if (base->sorter != NULL) {
00053 while (son > 0) {
00054 IndexSorter_Index dad = (son-1) / 2;
00055 IndexSorter_Index dx = vec[dad];
00056 if (base->sorter(base, dx, x) <= 0) break;
00057 vec[son] = dx;
00058 son = dad;
00059 }
00060 }
00061 vec[son] = x;
00062 base->len = len+1;
00063 }
00064
00065 extern IndexSorter_Index
00066 IndexSorter_Rem(IndexSorter_Base base) {
00067 IndexSorter_Index len = base->len;
00068 IndexSorter_Index ret = base->empty;
00069 if (len > 0) {
00070 IndexSorter_Index *vec = base->indexes;
00071 if (base->sorter != NULL) {
00072
00073 len = len - 1;
00074 ret = vec[0];
00075 IndexSorter_Index dad = 0;
00076 IndexSorter_Index dx = vec[len];
00077 for (;;) {
00078 IndexSorter_Index son = dad+dad+1;
00079 if (son >= len) break;
00080 IndexSorter_Index sx = vec[son];
00081 IndexSorter_Index nson = son+1;
00082 if (nson < len) {
00083 IndexSorter_Index sy = vec[nson];
00084 if (base->sorter(base, sx, sy) > 0) {
00085 sx = sy;
00086 son = nson;
00087 }
00088 }
00089 if (base->sorter(base, dx, sx) <= 0) break;
00090 vec[dad] = sx;
00091 dad = son;
00092 }
00093 vec[dad] = dx;
00094 } else {
00095
00096 len = len - 1;
00097 ret = vec[len];
00098 }
00099 base->len = len;
00100 }
00101 return ret;
00102 }
00103
00104 extern IndexSorter_Index
00105 IndexSorter_Best(IndexSorter_Base base) {
00106 if (base->len > 0) return base->indexes[0];
00107 return base->empty;
00108 }
00109
00110 extern void
00111 IndexSorter_Reset(IndexSorter_Base base) {
00112 base->len = 0;
00113 }
00114
00115 extern void
00116 IndexSorter_Free(IndexSorter_Base *basePtr) {
00117 if (basePtr != NULL) {
00118 IndexSorter_Base base = *basePtr;
00119 if (base != NULL) {
00120 void *indexes = base->indexes;
00121 if (indexes != NULL) free(indexes);
00122 free(base);
00123 }
00124 }
00125 }
00126