带头单链表的创建、打印和释放见博客 一:单链表的创建、打印和释放
1. 递归方式实现
思路:如果两个结点比较大小,较小结点指向较小结点后面的所有的结点和 较大结点及其后面结点 合并后的单链表。最简单情况两个结点其中一个为空,合并结果直接是另一个结点。
/*
* 递归实现两个有序单链表的合并
* @param[in] pNode1 NODE_t * :单链表的第一个有效结点
* @param[in] pNode2 NODE_t * :单链表的第一个有效结点
*/
NODE_t * MergeSortedSListRecur(NODE_t *pNode1, NODE_t *pNode2) {
if (pNode1 == NULL) {
return pNode2;
}
if (pNode2 == NULL) {
return pNode1;
}
NODE_t *pNode = NULL;
if (pNode1->iData < pNode2->iData) {
pNode = pNode1;
pNode->pNext = MergeSortedSListRecur(pNode1->pNext, pNode2);
}
else {
pNode = pNode2;
pNode->pNext = MergeSortedSListRecur(pNode1, pNode2->pNext);
}
return pNode;
}
2. 循环方式实现
思路:通过遍历,每次找出当前两条链中的最小结点进行链接
/*
* 循环实现两个有序单链表的合并
* @param[in] pNode1 NODE_t * :单链表的头结点
* @param[in] pNode2 NODE_t * :单链表的头结点
*/
NODE_t * MergeSortedSListCircle(NODE_t *pHead1, NODE_t *pHead2) {
if (pHead1 == NULL || pHead1->pNext == NULL) {
return pHead2;
}
if (pHead2 == NULL || pHead2->pNext == NULL) {
return pHead1;
}
NODE_t *pHead = NULL;
NODE_t *pOne = NULL;
NODE_t *pOther = NULL;
if (pHead1->pNext->iData < pHead2->pNext->iData) {
pHead = pHead1;
pOne = pHead1->pNext;
pOther = pHead2->pNext;
free(pHead2);
}
else {
pHead = pHead2;
pOne = pHead2->pNext;
pOther = pHead1->pNext;
free(pHead1);
}
NODE_t *pCur = pHead;
// 合并开始前,pOne已经指向最小的结点
while (pOne != NULL && pOther != NULL) {
if (pOne->iData < pOther->iData) {
pCur->pNext = pOne;
pOne = pOne->pNext;
pCur = pCur->pNext;
}
else {
pCur->pNext = pOther;
pOther = pOther->pNext;
pCur = pCur->pNext;
}
}
pCur->pNext = (pOne == NULL ? pOther : pOne);
return pHead;
}
3. 测试代码
int main() {
int aArray1[6] = { 1, 4, 5, 8, 30, 40 };
NODE_t *pSorted1 = CreateArraySList(aArray1, 6);
ShowSList(pSorted1);
int aArray2[6] = { 3, 4, 7, 10, 18, 35 };
NODE_t *pSorted2 = CreateArraySList(aArray2, 6);
ShowSList(pSorted2);
/*
NODE_t *pNewSorted = MergeSortedSListRecur(pSorted1->pNext, pSorted2->pNext);
pSorted1->pNext = pNewSorted;
free(pSorted2);
ShowSList(pSorted1);
*/
NODE_t *pNewSorted = MergeSortedSListCircle(pSorted1, pSorted2);
ShowSList(pNewSorted);
return 0;
}