1. 程式人生 > >cJSON排序(雙鏈表排序的另一種方式)

cJSON排序(雙鏈表排序的另一種方式)

雙鏈表排序演算法

本文提供一種雙鏈表排序方法,主要思路是:雙鏈表的next,prev 指標不變,即連結串列的前後關係不變,只交換連結串列中的資料內容;如升序排序,從開始向後兩兩比較,若前面A比後面大B,交換AB的內容,保證了是升序,但不能保證B比A前面的內容小,所以要向前遍歷,發現前面的比後面的大,交換資料;這樣向後一次遍歷完成,排序完成; 這樣做的好處是:比網上交換指標的那種演算法簡單,思路清晰; cJSON 是C語言處理 json的方法(cJSON.c和cJSON.h兩個檔案),具體用法可百度; cJSON 組的資料其實就是一個雙鏈表,所以用cJSON組json的資料作為雙鏈表的資料(這樣不用自己寫雙鏈表了); cJSON 的節點資料:

/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6

typedef struct cJSON {
	struct cJSON *next,*prev;	
	struct cJSON *child;		/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
	int type;					/* The type of the item, as above. */
	char *valuestring;			/* The item's string, if type==cJSON_String */
	int valueint;				/* The item's number, if type==cJSON_Number */
	double valuedouble;			/* The item's number, if type==cJSON_Number */
	char *string;				/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;

程式碼:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "cJSON.h"

/*只交換cJSON中的資料內容,不交換next,prev 指標,前後順數不變*/
int swapCont(cJSON *contSrc,cJSON *contDest)
{
	if(contSrc == NULL || contDest == NULL)
	{
		return -1;
	}

	cJSON tmpData;
	memset(&tmpData,0,sizeof(tmpData));
	tmpData.child = contSrc->child;
	tmpData.type = contSrc->type;
	tmpData.valuestring = contSrc->valuestring;
	tmpData.valueint = contSrc->valueint;
	tmpData.valuedouble = contSrc->valuedouble;
	tmpData.string = contSrc->string;

	contSrc->child = contDest->child;
	contSrc->type = contDest->type;
	contSrc->valuestring = contDest->valuestring;
	contSrc->valueint = contDest->valueint;
	contSrc->valuedouble = contDest->valuedouble;
	contSrc->string = contDest->string;

	contDest->child = tmpData.child;
	contDest->type = tmpData.type;
	contDest->valuestring = tmpData.valuestring;
	contDest->valueint = tmpData.valueint;
	contDest->valuedouble = tmpData.valuedouble;
	contDest->string = tmpData.string;

	return 0;
}

int sortJson(cJSON *jsonData)
{
	if(jsonData == NULL)
	{
		return 0;
	}
	
	int i = 0;
      int countArrItem = 0;
	int ret = 0;

	cJSON *p = jsonData;  // p 向後遍歷指標
	cJSON *srcData = p ;
      cJSON *destData = p;

	cJSON *head = p;
	cJSON *q = p;  // q 向前遍歷指標


	if(p->type == cJSON_Array)  /*陣列內容排序*/
	{
		countArrItem = cJSON_GetArraySize(p);
		for(i = 0;i<countArrItem;i++)
		{
			cJSON *arrData = cJSON_GetArrayItem(p,i);
			ret = sortJson(arrData->child);
			if(ret < 0)
			{
				return -1;
			}
		}
	}

	p = p->next;
	if(p == NULL)
	{
		return 0;
	}
	
	while(p != NULL)   //向後遍歷
    {
		if(p->type == cJSON_Array)
		{
			countArrItem = cJSON_GetArraySize(p);
			for(i = 0;i<countArrItem;i++)
			{
				cJSON *arrData = cJSON_GetArrayItem(p,i);
				ret = sortJson(arrData->child);
				if(ret < 0)
				{
					return -2;
				}
			}
		}	

		destData = p->prev;
		srcData = p;
	    if(strcmp(srcData->string,destData->string)<0) //升序 排序
		{
			ret = swapCont(srcData,destData);
			if (ret <0)
			{
				return -3;
			}
			
			q = p;
			while(q != head)   //向前遍歷
			{
				destData = q->prev;
			    srcData = q;
				if(strcmp(srcData->string,destData->string)<0)
				{
					ret = swapCont(srcData,destData);
					if (ret <0)
					{
						return -4;
					}
				}
				q = q->prev;
			}
		}
		p = p->next;
	}
	return 0;
}


int main(int argc,char* argv[])
{
	//測試資料
	cJSON *root = cJSON_CreateObject();
	
	cJSON *head ;
	cJSON_AddItemToObject(root,"head",head = cJSON_CreateObject());

	cJSON *arr;    
	cJSON_AddItemToObject(head,"mpp",arr = cJSON_CreateArray());
	cJSON *arrItem1,*arrItem2;
	cJSON_AddItemToArray(arr, arrItem1 = cJSON_CreateObject());
	cJSON_AddItemToObject(arrItem1,"prin",cJSON_CreateString("10.12"));
	cJSON_AddItemToObject(arrItem1,"amt",cJSON_CreateString("amt"));
	cJSON_AddItemToObject(arrItem1,"goodsNo",cJSON_CreateString("1"));
	cJSON_AddItemToArray(arr, arrItem2 = cJSON_CreateObject());
	cJSON_AddItemToObject(arrItem2,"prin",cJSON_CreateString("10.12"));
	cJSON_AddItemToObject(arrItem2,"goodsNo",cJSON_CreateString("2"));
	
	cJSON_AddItemToObject(head,"version",cJSON_CreateString("V1.0"));
	cJSON_AddItemToObject(head,"appid",cJSON_CreateString("123456"));
      cJSON_AddItemToObject(head,"exit",cJSON_CreateString("exit"));
      cJSON_AddItemToObject(head,"aba",cJSON_CreateString("890"));
	cJSON_AddItemToObject(head,"aa",cJSON_CreateString("rty"));
	char *prnStr = cJSON_Print(root);
	printf("排序前\n");
	printf("%s\n",prnStr);

	sortJson(head->child);
	
	printf("排序後\n");
	prnStr = cJSON_Print(root);
	printf("%s\n",prnStr);

	return 0;
}

效果如下:

排序前:
{
	"head":	{
		"mpp":	[{
				"prin":	"10.12",
				"amt":	"amt",
				"goodsNo":	"1"
			}, {
				"prin":	"10.12",
				"goodsNo":	"2"
			}],
		"version":	"V1.0",
		"appid":	"123456",
		"exit":	"exit",
		"aba":	"890",
		"aa":	"rty"
	}
}
排序後:
{
	"head":	{
		"aa":	"rty",
		"aba":	"890",
		"appid":	"123456",
		"exit":	"exit",
		"mpp":	[{
				"amt":	"amt",
				"goodsNo":	"1",
				"prin":	"10.12"
			}, {
				"goodsNo":	"2",
				"prin":	"10.12"
			}],
		"version":	"V1.0"
	}
}