单链表操作之合并两个有序单链表---递归 and 非递归实现

来源:互联网 发布:科比06年数据 编辑:程序博客网 时间:2024/05/17 06:28


问题提出:

现有无头结点有序单链表pHead1和无头结点有序单链表pHead2,要求将两个链表合并后依然有序。

如:   pHead1 为 1 3 5 7 9 

        pHead2 为 2 4 6 8 10

        合并后    为1 2 3 4 5 6 7 8 9





问题解决:


(1)递归实现
1.对空链表存在的情况进行处理,假如pHead1为空则返回pHead2,pHead2为空则返回pHead1。(两个都为空此情况在pHead1为空已经被拦截)
2.比较两个链表第一个结点的大小 确定 头结点的位置
3.头结点确定后 继续在剩下的结点中 选出下一个结点去链接到第二步选出的结点后面,然后在继续重复2 3步 直到有链表为空
   


举个实例:有有序单链表L1  (1  3  5  7  ),  L2  (2  4  6  8)
1.链表L1的第一个结点的值小于链表L2的第一个结点的值,因此链表1的头结点是合并后链表的头结点。
2.在剩下的结点中链表L2的第一个结点的值小于链表L1的第一个结点的值,因此将链表二的第一个结点与第一步的头结点连接。
3.然后继续在剩下的结点中重复第二、三步,直到有链表为空。


函数代码:

PNode MergeTwoOrderedLists(PNode pHead1, PNode pHead2){PNode newHead = NULL;if (NULL == pHead1){return pHead2;}else if(NULL ==pHead2){return pHead2;}else{if (pHead1->data < pHead2->data){newHead = pHead1;newHead->next = MergeTwoOrderedLists(pHead1->next, pHead2);} else{newHead = pHead2;newHead->next = MergeTwoOrderedLists(pHead1, pHead2->next); }return newHead;}}


(2)非递归实现
1.第一步与递归一样,对空链表存在的情况进行处理,假如pHead1为空则返回pHead2,pHead2为空则返回pHead1。(两个都为空此情况在pHead1为空已经被拦截)
2.在两个链表无空链表的情况下确定第一个结点,比较链表1和链表2的第一个结点的值,将值小的结点保存下来为合并后的第一个结点。并且把第一个结点为最小的链表向后移动一个元素。
3.继续在剩下的元素中选择小的值,连接到第一个结点后面,并不断next将值小的结点连接到第一个结点后面,直到某一个链表为空。
4.当两个链表长度不一致时,也就是比较完成后其中一个链表为空,此时需要把另外一个链表剩下的元素都连接到第一个结点的后面。

函数代码:

PNode MergeTwoOrderedLists(PNode pHead1, PNode pHead2){PNode pTail = NULL;//指向新链表的最后一个结点 pTail->next去连接PNode newHead = NULL;//指向合并后链表第一个结点if (NULL == pHead1){return pHead2;} else if(NULL == pHead2){return pHead1;}else{//确定头指针if ( pHead1->data < pHead2->data){newHead = pHead1;pHead1 = pHead1->next;  //指向链表的第二个结点} else{newHead = pHead2;pHead2 = pHead2->next;}pTail = newHead;    //指向第一个结点while ( pHead1 && pHead2)  {if ( pHead1->data <= pHead2->data ){pTail->next = pHead1;  pHead1 = pHead1->next;}else {pTail->next = pHead2;pHead2 = pHead2->next;}pTail = pTail->next;}if(NULL == pHead1){pTail->next = pHead2;}else if(NULL == pHead2){pTail->next = pHead1;}return newHead;}




源代码以及测试用例截图:

/**********************SingleList.h**********************/#define _CRT_SECURE_NO_WARNINGS   //去除函数不安全的警告#include <stdio.h>#include <stdlib.h>#include <assert.h>typedef int DataType;typedef struct Node{DataType data;struct Node* next;}Node,*PNode;//打印void PrintList(PNode pHead)//初始化一个空表void InitList(PNode* pHead);//生成一个新的结点PNode NewNode(DataType data);//合并两个有序链表 合并后仍然有序PNode MergeTwoOrderedLists(PNode pHead1, PNode pHead2);//头插void PushFront(PNode* pHead, DataType data);/**********************SingleList.c**********************///初始化void InitList(PNode* pHead){assert(pHead);*pHead = NULL;}//打印void PrintList(PNode pHead){while(pHead){printf("%d--> ",pHead->data);pHead = pHead->next;}printf("NULL\n");}//创建一个新结点PNode NewNode(DataType data){PNode temp = (PNode)malloc(sizeof(Node));if(temp){temp->data = data;temp->next = NULL;}return temp;}//头插void PushFront(PNode* pHead, DataType data){PNode tempNode = NULL;assert(pHead);if(NULL == *pHead){*pHead = NewNode(data);}else{tempNode = NewNode(data);tempNode ->next = *pHead;*pHead = tempNode;}}//合并两个有序链表 合并后仍然有序PNode MergeTwoOrderedLists(PNode pHead1, PNode pHead2){PNode pTail = NULL;//指向新链表的最后一个结点 pTail->next去连接PNode newHead = NULL;//指向合并后链表第一个结点if (NULL == pHead1){return pHead2;} else if(NULL == pHead2){return pHead1;}else{//确定头指针if ( pHead1->data < pHead2->data){newHead = pHead1;pHead1 = pHead1->next;    //指向链表的第二个结点} else{newHead = pHead2;pHead2 = pHead2->next;}pTail = newHead;    //指向第一个结点while ( pHead1 && pHead2)  {if ( pHead1->data <= pHead2->data ){pTail->next = pHead1;  pHead1 = pHead1->next;}else {pTail->next = pHead2;pHead2 = pHead2->next;}pTail = pTail->next;}if(NULL == pHead1){pTail->next = pHead2;}else if(NULL == pHead2){pTail->next = pHead1;}return newHead;}/**********************main.c**********************/void Test_MergeTwoOrderedLists(){PNode pHead1;PNode pHead2;PNode newHead;InitList(&pHead1);InitList(&pHead2);PushBack(&pHead1, 1);PushBack(&pHead1, 3);PushBack(&pHead1, 5);PushBack(&pHead1, 7);PushBack(&pHead2, 2);PushBack(&pHead2, 4);PushBack(&pHead2, 6);PushBack(&pHead2, 8);PrintList(pHead1);PrintList(pHead2);newHead = MergeTwoOrderedLists(pHead1, pHead2);PrintList(newHead);}Test_MergeTwoOrderedLists(){}int main(){Test_MergeTwoOrderedLists();return 0;}


1.正常情况

2.一个链表为空

3.两个链表都空



0 0
原创粉丝点击