单链表操作之合并两个有序单链表---递归 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;}
2.一个链表为空
3.两个链表都空
0 0
- 单链表操作之合并两个有序单链表---递归 and 非递归实现
- Java 非递归 和非递归方法 实现两个有序单链表的合并
- 合并两个有序单链表的递归方法
- 有序单链表的合并:递归和非递归方法
- 两个有序链表合并递归实现及非递归实现
- 合并两个有序链表的递归与非递归
- 合并两个有序链表(递归非递归方法)
- 合并两个有序链表(非递归与递归)
- 剑指offer--递归非递归合并两个有序链表
- 面试题17:合并两个有序链表,递归和非递归实现
- 链表面试题之合并有序的两个线性表-递归和非递归的方法
- 递归实现合并两个有序链表
- 合并两个有序链表,递归实现
- 求两个有序数组的中位数之非递归实现
- 合并有序单链表(递归实现)
- 非递归实现两个有序链表
- 合并两个链表递归和非递归实现
- 合并两个有序列表的循环和递归实现
- 求任意数列的全排列
- hdu 4990 Reading comprehension
- 第7.2章 root释疑,符号含义,常用的linux管理命令
- 2016 cocoapods的安装和使用以及版本升级遇到的问题
- Android开发性能优化之SparseArray和HashMap
- 单链表操作之合并两个有序单链表---递归 and 非递归实现
- 甘学长工作室-单片机protues仿真(毕业设计,课程设计,实训)
- linux程序设计:make命令和makefile文件
- 建立时间和保持时间
- CocoaLumberjack 之坑
- 自定义导航栏返回按钮
- 基于 LAMP 的 Typecho 博客搭建
- 面试
- UVA - 10305 Ordering Tasks