数据结构(5)线性表之链表C++实现带头结点的单链表合并
来源:互联网 发布:显示数据库字符集 编辑:程序博客网 时间:2024/06/06 05:03
- 题目
- 算法原节点上合并
- 算法动态演示
- 算法具体实现
- 运行结果
- 合并新节点方式
- 原题目第三篇文章的链表实现方式
- 算法动态演示
- 算法实现
- 运行结果
题目
如何将有序链表合并成有序链表
假设头指针为
思路点拨
按照第三篇文章的思想,需要设立三个指针pa,pb和pc,其中pa和pb分别指向La表和Lb表中待插入的结点,而pc指向Lc表中当前待插入的结点,而pc指向Lc表中当前最后一个结点,若
pa−>data≤pb−>data ,则将pa所指结点链接到pc所指结点之后,否则将pb所指结点链接到pc所指结点之后。
而明显的,指针的初始化状态:LA和LB为非空表时,pa和pb分别指向La和Lb表中第一个结点,否则为空;pc指向空表Lc中的头结点。由于链表的长度是隐含的,则第一个循环执行的条件应该是pa和pb皆非空(空表没有数值,无法比较大小,进行插入表c操作),当一个为空的时候,说明有一个表的元素已经归并完毕,则只要将另一个表的剩余段链接在pc所指的结点之后就可以了。
算法(原节点上合并)
void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc) { // 算法2.12 // 已知单链线性表La和Lb的元素按值非递减排列。 // 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。 LinkList pa, pb, pc; pa = La->next; pb = Lb->next; Lc = pc = La; // 用La的头结点作为Lc的头结点 while (pa && pb) { if (pa->data <= pb->data) { pc->next = pa; pc = pa; pa = pa->next; } else { pc->next = pb; pc = pb; pb = pb->next; } } pc->next = pa ? pa : pb; // 插入剩余段 free(Lb); // 释放Lb的头结点} // MergeList_L
算法动态演示
算法具体实现
//所有定义#define LIST_INIT_SIZE 100#define LISTINCREMENT 10#define OK 1#define ERROR 0#define OVERFLOW -2#define TRUE 1#define FALSE 0typedef int Status;//为了方便算法可用性,算法的Status可以通过这里可改typedef int ElemType;//为了输出的可用性,数据的ElemType可以通过这里更改struct LNode{ ElemType data; struct LNode *next;};typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 *///包含的头文件#include <iostream>using namespace std;Status InitList(LinkList *L){ /* 操作结果:构造一个空的线性表L */ *L = (LinkList)malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */ if (!*L) /* 存储分配失败 */ exit(OVERFLOW); (*L)->next = NULL; /* 指针域为空 */ return OK;}Status ClearList(LinkList &L) /* 不改变L */{ /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */ LinkList p, q; p = L->next; /* p指向第一个结点 */ while (p) /* 没到表尾 */ { q = p->next; free(p); p = q; } L->next = NULL; /* 头结点指针域为空 */ return OK;}void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc) { // 算法2.12 // 已知单链线性表La和Lb的元素按值非递减排列。 // 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。 LinkList pa, pb, pc; pa = La->next; pb = Lb->next; Lc = pc = La; // 用La的头结点作为Lc的头结点 while (pa && pb) { if (pa->data <= pb->data) { pc->next = pa; pc = pa; pa = pa->next; } else { pc->next = pb; pc = pb; pb = pb->next; } } pc->next = pa ? pa : pb; // 插入剩余段 free(Lb); // 释放Lb的头结点} // MergeList_LStatus ListInsert_L(LinkList &L, int i, ElemType e) { // 算法2.9 // 在带头结点的单链线性表L的第i个元素之前插入元素e LinkList p, s; p = L; int j = 0; while (p && j < i - 1) { // 寻找第i-1个结点 p = p->next; ++j; } if (!p || j > i - 1) return ERROR; // i小于1或者大于表长 s = (LinkList)malloc(sizeof(LNode)); // 生成新结点 s->data = e; s->next = p->next; // 插入L中 p->next = s; return OK;} // LinstInsert_LStatus ListTraverse(LinkList L, void(*vi)(LinkList&)){ /* 初始条件:顺序线性表L已存在 */ /* 操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */ LinkList p = L->next; cout << " "; while (p != NULL) { vi(p); p = p->next; } return OK;}void visit(LinkList &node){ cout <<node->data << " ";}int main(){ //创建三个表 LinkList A, B, C; //本程序说明,是在VS2013中运行的,若是其他地方无法运行,建议修改代码 //程序声明 cout << "***************************************************************************" << endl; cout << " 《数据结构》<C语言版本>严蔚敏 吴伟名 编著 " << endl; cout << " 编写年月2016年3月 " << endl; cout << " 编写者:YuYunTan " << endl; cout << " 算法2.11 " << endl; cout << "***************************************************************************" << endl; //test1 cout << "Test 1:" << endl; //表的初始化,即每一个表都能有一个头结点,方便进行指向使用 //状态判断 if (InitList(&A) == OK && InitList(&B) == OK) { //表都能初始化 //给A表插入数据 ListInsert_L(A, 1, 16); ListInsert_L(A, 2, 29); //输出表A cout << " List A = <"; ListTraverse(A, visit); cout << ">" << endl; //B表插入数据 ListInsert_L(B, 1, 22); ListInsert_L(B, 2, 22); ListInsert_L(B, 3, 28); ListInsert_L(B, 4, 28); ListInsert_L(B, 5, 46); //输出表B cout << " List B = <"; ListTraverse(B, visit); cout << ">" << endl; //合并表A和表B cout << " MergeList_L(A, B, C);"; MergeList_L(A, B, C); cout << endl; //输出表C cout << " List C = <"; ListTraverse(C, visit); cout << ">" << endl; LinkList A1, B1, C1; InitList(&A1); InitList(&B1); //重新插入元素 cout << "Test 2:" << endl; //给A表插入数据 ListInsert_L(A1, 1, 2); ListInsert_L(A1, 2, 4); ListInsert_L(A1, 3, 7); ListInsert_L(A1, 4, 16); ListInsert_L(A1, 5, 23); ListInsert_L(A1, 6, 31); ListInsert_L(A1, 7, 45); ListInsert_L(A1, 8, 56); ListInsert_L(A1, 9, 57); ListInsert_L(A1, 10, 58); //输出表A cout << " List A = <"; ListTraverse(A1, visit); cout << ">" << endl; //B表插入数据 ListInsert_L(B1, 1, 16); ListInsert_L(B1, 2, 17); ListInsert_L(B1, 3, 24); ListInsert_L(B1, 4, 56); //输出表B cout << " List B = <"; ListTraverse(B1, visit); cout << ">" << endl; //合并表A和表B cout << " MergeList_L(A, B, C);"; MergeList_L(A1, B1, C1); cout << endl; //输出表C cout << " List C = <"; ListTraverse(C1, visit); cout << ">" << endl; LinkList A2, B2, C2; InitList(&A2); InitList(&B2); //重新插入元素 cout << "Test 3:" << endl; //给A表插入数据 ListInsert_L(A2, 1, 16); ListInsert_L(A2, 2, 25); ListInsert_L(A2, 3, 27); ListInsert_L(A2, 4, 28); ListInsert_L(A2, 5, 37); ListInsert_L(A2, 6, 40); ListInsert_L(A2, 7, 40); ListInsert_L(A2, 8, 46); ListInsert_L(A2, 9, 53); ListInsert_L(A2, 10, 53); //输出表A cout << " List A = <"; ListTraverse(A2, visit); cout << ">" << endl; //B表插入数据 ListInsert_L(B2, 1, 13); ListInsert_L(B2, 2, 16); ListInsert_L(B2, 3, 22); ListInsert_L(B2, 4, 50); ListInsert_L(B2, 5, 59); //输出表B cout << " List B = <"; ListTraverse(B2, visit); cout << ">" << endl; //合并表A和表B cout << " MergeList_L(A, B, C);"; MergeList_L(A2, B2, C2); cout << endl; //输出表C cout << " List C = <"; ListTraverse(C2, visit); cout << ">" << endl; LinkList A3, B3, C3; InitList(&A3); InitList(&B3); //重新插入元素 cout << "Test 4:" << endl; //给A表插入数据 ListInsert_L(A3, 1, 9); //输出表A cout << " List A = <"; ListTraverse(A3, visit); cout << ">" << endl; //输出表B cout << " List B = <"; ListTraverse(B3, visit); cout << ">" << endl; //合并表A和表B cout << " MergeList_L(A, B, C);"; MergeList_L(A3, B3, C3); cout << endl; //输出表C cout << " List C = <"; ListTraverse(C3, visit); cout << ">" << endl; } else { cout << "error:don't create LinkList,malloc is fall!"; } system("pause"); return 0;}
运行结果
合并(新节点方式)
原题目(第三篇文章的链表实现方式)
假设利用两个线性表
void Union(LinkList a, LinkList b, LinkList &c){// 已知单链线性表La和Lb的元素按值非递减排列。 // 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。 // Lc采取新节点方式 c = (LinkList)malloc(sizeof(LNode)); pa = a->next; pb = b->next; pc = c;//c指向当前Lc的表头 while (pa || pb) { tp = (LinkList)malloc(sizeof(LNode));//临时结点 pc->next = tp; pc = tp;//pc指向当前节点 if (!pa){ pc->data = pb->data; pb = pb->next; } else if(!pb){ pc->data = pa->data; pa = pa->next; } else if (pa->data == pb->data){ pc->data = pa->data; pa = pa->next; pb = pb->next; } else if (pa->data < pb->data) { pc->data = pa->data; pa = pa->next; } else { pc->data = pb->data; pb = pb->next; } } pc->next = NULL;}Union
算法动态演示
算法实现
//所有定义#define LIST_INIT_SIZE 100#define LISTINCREMENT 10#define OK 1#define ERROR 0#define OVERFLOW -2#define TRUE 1#define FALSE 0typedef int Status;//为了方便算法可用性,算法的Status可以通过这里可改typedef char ElemType;//为了输出的可用性,数据的ElemType可以通过这里更改struct LNode{ ElemType data; struct LNode *next;};typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 *///包含的头文件#include <iostream>using namespace std;Status InitList(LinkList *L){ /* 操作结果:构造一个空的线性表L */ *L = (LinkList)malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */ if (!*L) /* 存储分配失败 */ exit(OVERFLOW); (*L)->next = NULL; /* 指针域为空 */ return OK;}Status ClearList(LinkList &L) /* 不改变L */{ /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */ LinkList p, q; p = L->next; /* p指向第一个结点 */ while (p) /* 没到表尾 */ { q = p->next; free(p); p = q; } L->next = NULL; /* 头结点指针域为空 */ return OK;}void Union(LinkList a, LinkList b, LinkList &c){// 已知单链线性表La和Lb的元素按值非递减排列。 // 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。 // Lc采取新节点方式 c = (LinkList)malloc(sizeof(LNode)); LinkList pa, pb, pc,tp; pa = a->next; pb = b->next; pc = c;//c指向当前Lc的表头 while (pa || pb) { tp = (LinkList)malloc(sizeof(LNode));//临时结点 pc->next = tp; pc = tp;//pc指向当前节点 if (!pa){ pc->data = pb->data; pb = pb->next; } else if(!pb){ pc->data = pa->data; pa = pa->next; } else if (pa->data == pb->data){ pc->data = pa->data; pa = pa->next; pb = pb->next; } else if (pa->data < pb->data) { pc->data = pa->data; pa = pa->next; } else { pc->data = pb->data; pb = pb->next; } } pc->next = NULL;}Status ListInsert_L(LinkList &L, int i, ElemType e) { // 算法2.9 // 在带头结点的单链线性表L的第i个元素之前插入元素e LinkList p, s; p = L; int j = 0; while (p && j < i - 1) { // 寻找第i-1个结点 p = p->next; ++j; } if (!p || j > i - 1) return ERROR; // i小于1或者大于表长 s = (LinkList)malloc(sizeof(LNode)); // 生成新结点 s->data = e; s->next = p->next; // 插入L中 p->next = s; return OK;} // LinstInsert_LStatus ListTraverse(LinkList L, void(*vi)(LinkList&)){ /* 初始条件:顺序线性表L已存在 */ /* 操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */ LinkList p = L->next; cout << " "; while (p != NULL) { vi(p); p = p->next; } return OK;}void visit(LinkList &node){ cout <<node->data << " ";}int main(){ //创建三个表 LinkList A, B, C; //本程序说明,是在VS2013中运行的,若是其他地方无法运行,建议修改代码 //程序声明 cout << "***************************************************************************" << endl; cout << " 《数据结构》<C语言版本>严蔚敏 吴伟名 编著 " << endl; cout << " 编写年月2016年3月 " << endl; cout << " 编写者:YuYunTan " << endl; cout << " 算法2.11 " << endl; cout << "***************************************************************************" << endl; //test1 cout << "Test 1:" << endl; //表的初始化,即每一个表都能有一个头结点,方便进行指向使用 //状态判断 if (InitList(&A) == OK && InitList(&B) == OK) { //表都能初始化 //给A表插入数据 ListInsert_L(A, 1, 'A'); ListInsert_L(A, 2, 'F'); //输出表A cout << " List A = <"; ListTraverse(A, visit); cout << ">" << endl; //B表插入数据 ListInsert_L(B, 1, 'A'); ListInsert_L(B, 2, 'D'); ListInsert_L(B, 3, 'E'); ListInsert_L(B, 4, 'F'); ListInsert_L(B, 5, 'L'); //输出表B cout << " List B = <"; ListTraverse(B, visit); cout << ">" << endl; //合并表A和表B cout << " Union(A, B, C);"; Union(A, B, C); cout << endl; //输出表C cout << " List C = <"; ListTraverse(C, visit); cout << ">" << endl; LinkList A1, B1, C1; InitList(&A1); InitList(&B1); //重新插入元素 cout << "Test 2:" << endl; //给A表插入数据 ListInsert_L(A1, 1, 'T'); //输出表A cout << " List A = <"; ListTraverse(A1, visit); cout << ">" << endl; //B表插入数据 ListInsert_L(B1, 1, 'E'); ListInsert_L(B1, 2, 'G'); //输出表B cout << " List B = <"; ListTraverse(B1, visit); cout << ">" << endl; //合并表A和表B cout << " Union(A, B, C);"; Union(A1, B1, C1); cout << endl; //输出表C cout << " List C = <"; ListTraverse(C1, visit); cout << ">" << endl; LinkList A2, B2, C2; InitList(&A2); InitList(&B2); //重新插入元素 cout << "Test 3:" << endl; //给A表插入数据 ListInsert_L(A2, 1, 'B'); ListInsert_L(A2, 2, 'E'); ListInsert_L(A2, 3, 'F'); ListInsert_L(A2, 4, 'G'); ListInsert_L(A2, 5, 'J'); ListInsert_L(A2, 6, 'L'); ListInsert_L(A2, 7, 'M'); //输出表A cout << " List A = <"; ListTraverse(A2, visit); cout << ">" << endl; //B表插入数据 ListInsert_L(B2, 1, 'S'); //输出表B cout << " List B = <"; ListTraverse(B2, visit); cout << ">" << endl; //合并表A和表B cout << " Union(A, B, C);"; Union(A2, B2, C2); cout << endl; //输出表C cout << " List C = <"; ListTraverse(C2, visit); cout << ">" << endl; LinkList A3, B3, C3; InitList(&A3); InitList(&B3); //重新插入元素 cout << "Test 4:" << endl; //给A表插入数据 ListInsert_L(A3, 1, 'G'); //输出表A cout << " List A = <"; ListTraverse(A3, visit); cout << ">" << endl; //输出表B cout << " List B = <"; ListTraverse(B3, visit); cout << ">" << endl; //合并表A和表B cout << " Union(A, B, C);"; Union(A3, B3, C3); cout << endl; //输出表C cout << " List C = <"; ListTraverse(C3, visit); cout << ">" << endl; } else { cout << "error:don't create LinkList,malloc is fall!"; } system("pause"); return 0;}
运行结果
2 0
- 数据结构(5)线性表之链表C++实现带头结点的单链表合并
- 《数据结构进行曲》 带头结点单循环链表的合并
- 数据结构学习之路-第二章:带头结点的线性链表
- 带头结点的线性链表的实现
- 带头结点的线性链表的编写与实现
- 线性表——带头结点单链表的实现
- 线性表——带头结点单链表的实现
- 线性表 - 带头结点的循环单链表
- 线性表(带头结点的单链表)
- 带头结点的线性链表类型
- 带头结点的线性链表类型
- 带头结点的线性链表类型
- 《数据结构》带头结点单链表的合并
- 数据结构 带头结点的单链表 操作大全 最全的链表操作(c++实现)
- 数据结构(四)——单链表 、带头结点的单链表、循环链表 及其实现
- 数据结构(二)——单链表 、带头结点的单链表、循环链表 及其实现
- 2-9-扩展的线性单链表(带头结点)-线性表-第2章-《数据结构》课本源码-严蔚敏吴伟民版
- 数据结构-java与c实现带头结点的单链表
- JSP 中文问题完全解决方案
- tomcat类加载器-with源码
- wmap安装过程的问题解决
- ViewPager+LinearLayout实现带索引的图片滑动
- HDU2504又见GCD
- 数据结构(5)线性表之链表C++实现带头结点的单链表合并
- Hadoop FS Shell命令大全
- 数组面试题
- MATLAB下载及安装
- ZBrush中的Alt和Shift键该如何进行运用
- C++类外直接访问私有成员
- linux 命令
- 第八届河南省程序设计大赛-NYOJ-1241-Distribution(水题)
- String,String[]与ArrayList<String>互转