sortnods.c

来自「傅立叶变换和小波变换是图像压缩的重要工具。该代大戏是利用小波变换进行图像压缩。」· C语言 代码 · 共 355 行

C
355
字号
#include <stdlib.h>
#include <string.h>
#include <crblib/inc.h>
#include <time.h>

// #define RADIX /* has bugs */

typedef struct SortNodeStruct SortNode;

struct SortNodeStruct
  {
  SortNode * Next;
  ulong Index;
  ubyte * MoreIndexPtr;
  void * Data;
  };

bool Sort_List(SortNode ** BasePtr);
bool Sort_Array(SortNode ** Array,int Num);

/* **/

void Sort_FreeStringNode(SortNode * N)
{
if ( !N ) return;
free( N->MoreIndexPtr - 4 );
free(N);
}

void Sort_FreeStringList(SortNode * N)
{
SortNode * next;
	while(N) {
		next = N->Next;
		Sort_FreeStringNode(N);
		N = next;
	}
}

static ulong Sort_MakeString_Counter = 0;

SortNode * Sort_MakeStringNode(const char * String)
{
ubyte *StrData;
SortNode * N;
size_t StringLen;

StringLen = strlen(String);

if ( (N = (SortNode *) malloc(sizeof(SortNode))) == NULL ) return(NULL);

if ( (StrData = malloc(StringLen + 1 + sizeof(ulong))) == NULL )
	{ free(N); return(NULL); }

memcpy(StrData,String,StringLen+1);
memcpy(StrData + StringLen + 1,(ubyte *)&Sort_MakeString_Counter,
	sizeof(ulong));
Sort_MakeString_Counter++;

N->Data = NULL;
N->Index = getulong(StrData);
N->MoreIndexPtr = StrData + 4;
N->Next = NULL;

return(N);
}

bool Sort_List(SortNode ** BasePtr)
{
SortNode ** Array;
int ArraySize,i;
SortNode * CurNode;

CurNode = *BasePtr;
if ( !CurNode || !CurNode->Next ) return(1);
ArraySize = 0;
while(CurNode) { ArraySize++; CurNode = CurNode->Next; }

if ( (Array = malloc(sizeofpointer*ArraySize)) == NULL )
  return(0);

i = 0;
CurNode = *BasePtr;
while(CurNode) { Array[i++] = CurNode; CurNode = CurNode->Next; }

if ( ! Sort_Array(Array,ArraySize) )
  { free(Array); return(0); }

i = 0;
CurNode = Array[0];
*BasePtr = CurNode;
i++;
while(i<ArraySize)
  {
  CurNode->Next = Array[i++];
  CurNode = CurNode->Next;
  }
CurNode->Next = NULL;

free(Array);
return(1);
}

static bool QS_InUse = 0; /* semaphore */
static SortNode ** QSArray; /* locked by semaphore */
static void QS(long L,long R);

bool Sort_Array_Past(SortNode ** Array,int ArraySize,int R_PastBytes)
{
if ( ArraySize <= 1 ) return(1);
#ifdef RADIX
if ( ArraySize <= 64 )
	{
#endif
	if ( QS_InUse ) return(0);

	QS_InUse = 1;
	QSArray = Array;
	QS(0,ArraySize-1);
	QS_InUse = 0;

	return(1);
#ifdef RADIX
	}
else
	{
	int R_NumBuckets,R_UseBytes;
	SortNode ** R_Buckets=NULL;
	SortNode ** tempArray=NULL;
	int R_Index,arrayI,tempLen,tempI;
	SortNode * curSN;

	if ( ArraySize > 8192 && R_PastBytes != 3 ) /* radix on word */
		{
		R_NumBuckets = 0x10000;
		R_UseBytes = 2;
		}
	else /* radix on byte */
		{
		R_NumBuckets = 0x100;
		R_UseBytes = 1;
		}

	if ( (R_Buckets = malloc(R_NumBuckets*sizeofpointer)) == NULL )
		goto R_Sort_Array_BadReturn;
	if ( (tempArray = malloc(ArraySize*sizeofpointer)) == NULL )
		goto R_Sort_Array_BadReturn;
	MemClearFast(R_Buckets,R_NumBuckets);

	if ( R_PastBytes >= 4 ) /* need to use MoreIndex */
		{
		int R_Offset = R_PastBytes-4;
		if(R_UseBytes==1)
			{
			for(arrayI=0;arrayI<ArraySize;arrayI++)
				{
				R_Index = Array[arrayI]->MoreIndexPtr[R_Offset];
				Array[arrayI]->Next = R_Buckets[R_Index];
				R_Buckets[R_Index] = Array[arrayI];
				}
			}
		else //(R_UseBytes==2)
			{
			for(arrayI=0;arrayI<ArraySize;arrayI++)
				{
				R_Index = (	Array[arrayI]->MoreIndexPtr[R_Offset] << 8) +
										Array[arrayI]->MoreIndexPtr[R_Offset+1];
				Array[arrayI]->Next = R_Buckets[R_Index];
				R_Buckets[R_Index] = Array[arrayI];
				}
			}
		}
	else /* do it with shifts */
		{
		int R_Mask = R_NumBuckets - 1;
		int R_ShiftBack = 32 - ((R_UseBytes+R_PastBytes)<<3);
		for(arrayI=0;arrayI<ArraySize;arrayI++)
			{
			R_Index = ((Array[arrayI]->Index) >> R_ShiftBack) & R_Mask;
			Array[arrayI]->Next = R_Buckets[R_Index];
			R_Buckets[R_Index] = Array[arrayI];
			}
		}

	arrayI=0;
	for(R_Index=0;R_Index<R_NumBuckets;R_Index++)
		{
		curSN = R_Buckets[R_Index]; tempI=0;
		while(curSN)
			{
			tempArray[tempI++] = curSN;
			curSN = curSN->Next;
			}
		tempLen = tempI;
		if ( tempLen>=1 )
			{
			if(!Sort_Array_Past(tempArray,tempLen,R_PastBytes+R_UseBytes))
				goto R_Sort_Array_BadReturn;
			for(tempI=0;tempI<tempLen;tempI++)
				Array[arrayI++] = tempArray[tempI++];
			}
		}

	free(tempArray);
	free(R_Buckets);

	if ( arrayI != ArraySize )
		goto R_Sort_Array_BadReturn;
	
	return 1;

	R_Sort_Array_BadReturn:

	if(R_Buckets) free(R_Buckets);
	if(tempArray) free(tempArray);

	return 0;
	}
#endif
return 0;
}


int NodeCompare(const void * v1,const void *v2)
{
SortNode *N1 = *((SortNode **)v1);
SortNode *N2 = *((SortNode **)v2);
if ( N1->Index == N2->Index )
	return strcmp(N1->MoreIndexPtr,N2->MoreIndexPtr);
return (N1->Index - N2->Index);
}

bool Sort_Array_clib(SortNode ** Array,int ArraySize)
{
qsort( Array,ArraySize,sizeofpointer,NodeCompare );
return(1);
}

bool Sort_Array(SortNode ** Array,int ArraySize)
{
//return( Sort_Array_Past(Array,ArraySize,0) );
return( Sort_Array_clib(Array,ArraySize) );
}

static void QS(long Left,long Right)
{
if ( (Right - Left) > 1 )
  {
  long i;

    {
    long j;
    ulong pivot;
    SortNode *swapper;
    SortNode ** Array;
    bool KeepGoing;
    ubyte * morepivotptr;

    Array = QSArray;

    pivot = Array[Right]->Index;
    morepivotptr = Array[Right]->MoreIndexPtr;

    i = Left-1;
    j = Right;
    for(;;)
      {
      do
        {
        ++i;
        if ( i == Right ) KeepGoing = 0;
        else
          {
          if ( Array[i]->Index < pivot ) KeepGoing = 1;
          else if ( Array[i]->Index == pivot )
            {
            ubyte * MoreIndexPtr = Array[i]->MoreIndexPtr;
            ubyte * curmorepivotptr = morepivotptr;
  
            while(*MoreIndexPtr == *curmorepivotptr)
              { MoreIndexPtr++; curmorepivotptr++; }
  
            if ( *MoreIndexPtr < *curmorepivotptr )
              KeepGoing = 1;
            else
              KeepGoing = 0;
            }
          else KeepGoing = 0;
          }
        } while(KeepGoing);

      do
        {
        --j;
        if ( Array[j]->Index > pivot ) KeepGoing = 1;
        else if ( Array[j]->Index == pivot )
          {
          ubyte * MoreIndexPtr = Array[j]->MoreIndexPtr;
          ubyte * curmorepivotptr = morepivotptr;

          while(*MoreIndexPtr == *curmorepivotptr)
            { MoreIndexPtr++; curmorepivotptr++; }

          if ( *MoreIndexPtr > *curmorepivotptr )
            KeepGoing = 1;
          else
            KeepGoing = 0;
          }
        else KeepGoing = 0;
        } while(KeepGoing && j > Left);

      if (i >= j) break;
      swapper  = Array[i];
      Array[i] = Array[j];
      Array[j] = swapper;
      }
    swapper  = Array[i];
    Array[i] = Array[Right];
    Array[Right] = swapper;
    }

  QS(Left,i-1);
  QS(i+1,Right);
  }
else
  {
  if ( Right > Left )
    {
    if ( QSArray[Right]->Index < QSArray[Left]->Index )
      {
      SortNode *swapper;

      swapper  = QSArray[Left];
      QSArray[Left] = QSArray[Right];
      QSArray[Right] = swapper;
      }
    else if ( QSArray[Right]->Index == QSArray[Left]->Index )
      {
      ubyte *rptr=QSArray[Right]->MoreIndexPtr;
      ubyte *lptr=QSArray[Left]->MoreIndexPtr;

      while(*rptr == *lptr) { rptr++; lptr++; }
      if ( *rptr < *lptr )
        {
        SortNode *swapper;

        swapper  = QSArray[Left];
        QSArray[Left] = QSArray[Right];
        QSArray[Right] = swapper;
        }
      }
    }
  }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?