您的位置:首页 > 其它

单链表的原地归并排序实现

2011-10-05 16:43 323 查看
转载:http://www.cnblogs.com/sgzxy/archive/2009/06/14/1502975.html

#include <stdlib.h>

template<class T>

struct Node

{

Node(T d)

{

data = d;

next = NULL;

}

T data;

Node *next;

};

template<class T>

Node<T> * GetTailNode( Node<T> *startNode, int length )

//按长度找到尾节点

{

while(length-- && startNode->next != NULL)

{

startNode = startNode->next;

}

return startNode;

}

template<class T, class CmpFunc>

Node<T> * Merge( Node<T> *&startNode, int currBlockLen, CmpFunc cmp )

//从startNode开始,按currBlockLen二分,进行归并操作

{

bool canMerge = true;

Node<int> *leftBlock = startNode, *rightBlock = startNode;

// 找到rightBlock的头节点

for(int i = 0; i<currBlockLen; ++i)

{

rightBlock = rightBlock->next;

if(rightBlock == NULL)

{

canMerge = false;

break;

}

}

if(!canMerge)

return NULL;

Node<int> *currSortedNode; //排序结果的当前节点

Node<int> *currTailNode = NULL; //排序结果的尾节点,用于最后将排序结果与下一段链表数据连接

int leftCount = 0, rightCount = 0;

//初始化currSortedNode

if( cmp(leftBlock->data, rightBlock->data) )

{

++rightCount;

currSortedNode = startNode = rightBlock;

rightBlock = rightBlock ->next;

}

else

{

++leftCount;

currSortedNode = leftBlock;

leftBlock = leftBlock ->next;

}

while(true)

{

if(leftCount == currBlockLen || leftBlock == NULL )

//当leftBlock完成排序时,leftBlock尾节点即为currSortedNode

{

currSortedNode->next = rightBlock; //剩下的rightBlock无需再排序,直接加入结果链

currTailNode = GetTailNode( currSortedNode, currBlockLen-rightCount ); //找到结果的尾节点

break;

}

else if(rightCount == currBlockLen || rightBlock == NULL )

//当右Block完成排序,此时右Block的尾节点即为currSortedNode

{

Node<T> *tmpNode = currSortedNode->next; //记下下一段链表的头节点

currSortedNode->next = leftBlock;

currTailNode = GetTailNode( currSortedNode, currBlockLen-leftCount );

currTailNode->next = tmpNode; //将结果链表与下一段链表连起来

break;

}

else

//普通的归并操作

{

if(cmp(leftBlock->data, rightBlock->data))

{

++rightCount;

currSortedNode->next = rightBlock;

rightBlock = rightBlock->next;

}

else

{

++leftCount;

currSortedNode->next = leftBlock;

leftBlock = leftBlock->next;

}

currSortedNode = currSortedNode->next;

}

}

return currTailNode->next != NULL ? currTailNode : NULL; //返回NULL意味着一轮归并的结束

}

template<class T, class CmpFunc>

void MergeSort( Node<T>* &dataLink, CmpFunc cmp )

{

int currBlockLen = 1;

Node<T> *lastTailNode;

while( true )

{

lastTailNode = Merge( dataLink, currBlockLen, cmp );

if(lastTailNode != NULL)

{

do

{

lastTailNode = Merge( lastTailNode->next, currBlockLen, cmp );

}

while ( lastTailNode != NULL );

currBlockLen *= 2;

}

else

break;

}

}

inline bool IntCmp( int &a, int &b )

{

return a>b;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: