/********************************************************************
* File Name : insert_sort.c *
* Created : 2007/05/08 *
* Author : SunYonggao *
* Description : 插入排序的實現 非遞減排序 *
/* 如果是順序表的化可以用二份插入排序提高效率
*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//定義類型 所有的排序例子中都是用的int作為data
typedef int elemType;
//傳回值
#define RET_SUCCESS ( 1 )
#define RET_FAILED ( 0 )
//定義鏈表的長度
#define LIST_MAX_SIZE (10)
//定義鏈表申請記憶體不夠時報錯資訊
#define NO_MEMORY printf("Error! Not enough memory!/n");exit(1)
//結構體定義
typedef struct tagNode_t
{
elemType data;
struct tagNode_t * pstNext;
}node_t;
// 初始化鏈表 鏈表在外部定義 node_t * pstHead
// 調用時要用 initList(&pstHead)的形式 注意前端節點的內容為空白僅僅為了操作方便
// 隨機產生0-LIST_MAX_SIZE的數字作為鏈表的data
int initList(node_t ** pstHead)
{
int iRet = RET_SUCCESS;
int iCir = 0;
node_t * pstTmp1 = NULL;
node_t * pstTmp2 = NULL;
//初始化前端節點
* pstHead = (node_t *)malloc(sizeof(node_t));
if ( !pstHead )
{
NO_MEMORY;
}
pstTmp1 = * pstHead;
//鏈表初始化
srand( time(NULL) );//隨機數
for( iCir = 0; iCir < LIST_MAX_SIZE; iCir++ )
{
pstTmp2 = (node_t *)malloc(sizeof(node_t));
if ( !pstTmp2 )
{
NO_MEMORY;
}
//賦初值
pstTmp2->data = rand() % LIST_MAX_SIZE;
pstTmp2->pstNext = NULL;
pstTmp1->pstNext = pstTmp2;
pstTmp1 = pstTmp2;
}
return iRet;
}
// 列印鏈表 鏈表的data元素是可列印的整形
int showList(node_t * pstHead)
{
int iRet = RET_SUCCESS;
node_t * pstTmp = pstHead->pstNext;
if ( NULL == pstHead )
{
printf("鏈表的前端節點是空/n");
iRet = RET_FAILED;
}
else
{
while ( pstTmp )
{
printf("%d ", pstTmp->data);
pstTmp = pstTmp->pstNext;
}
printf("/n");
}
return iRet;
}
/* 刪除包括前端節點在內的所有的節點. 07/04/28 */
int destroyList(node_t * pstHead)
{
node_t * pstTmp = NULL; /* Temp pointer for circle */
int iRet = RET_SUCCESS;
if ( !pstHead )
{
printf("Error! pstHead is null/n");
iRet = RET_FAILED;
}
else
{
while ( pstHead ) /* Free nodes */
{
pstTmp = pstHead;
pstHead = pstHead->pstNext;
free(pstTmp);
}
pstHead = NULL;
}
return iRet;
}/* End of destroyList----------------------------------------------*/
//插入排序
void insert_sort(node_t * pstHead)
{
node_t * pstToSort = NULL;
node_t * pstTmpHead = NULL;
node_t * pstTmp = NULL;
if ( !pstHead )
{
printf("錯誤!前端節點為空白./n");
exit(1);
}
if ( pstHead->pstNext && pstHead->pstNext->pstNext )//如果只有一個元素則不用排序
{
pstToSort = pstHead->pstNext->pstNext;//要排序的部分的前端節點 第一個不用排序
pstTmpHead = pstHead;
pstTmpHead->pstNext->pstNext = NULL; //將第一個元素先掛上
while ( pstToSort )
{
while ( pstTmpHead->pstNext && pstToSort->data > pstTmpHead->pstNext->data )
{
pstTmpHead = pstTmpHead->pstNext;
}
pstTmp = pstToSort; //將帶排序的最前面的節點取出
pstToSort = pstToSort->pstNext; //帶排序鏈表前端節點後移
pstTmp->pstNext = pstTmpHead->pstNext;//插入pstTmp
pstTmpHead->pstNext = pstTmp;
pstTmpHead = pstHead;//pstTmpHead指向前端節點進行新一輪插入
}
}
}
//入口函數
void main()
{
node_t * pstHead = NULL;
initList(&pstHead);//初始化鏈表
printf("pai qian /n");
showList(pstHead);//列印元素
insert_sort(pstHead);//插入排序
printf("pai hou/n");
showList(pstHead);
destroyList(pstHead);
pstHead = NULL;
}
/* End of file ----------------------------------------------------*/