c语言实现单链表的合并 归并算法

合集下载

基于单链表实现集合的交集、并集、差集的运算

基于单链表实现集合的交集、并集、差集的运算

基于单链表实现集合的交集、并集、差集的运算解题思路(单链表求交集、并集、差集的思想和顺序表求交集、并集、差集的思想基本相同)1.先通过CreateListR 函数将集合 a 和 b 中的元素添加到顺序表 ha 和 hb 中,添加过程使⽤的是顺序表原有的Initlist 函数(初始化表)和ListInsert 函数(向表中插⼊元素)。

2.因为原集合是⽆序的,所以我通过 sort 函数(选择排序),使得集合变得有序。

3.得到有序集合 ha 和 hb 后,便可以使⽤ Union 函数(类似归并的思想写出来的求并集的函数),求出 ha 和 hb 的并集。

4.⽽求交集的⽅法则是,通过将集合 a 中的元素⼀个⼀个取出,并通过函数LocateElem ,查看集合 hb 中是否存在该元素,如果存在则将元素放⼊ hc ,如果不存在,则舍去。

以此求得两集合的交集。

5.求两集合的差则可以反过来,同样通过将集合 a 中的元素⼀个⼀个取出,并通过函数LocateElem ,查看集合 hb 中是否存在该元素,如果不存在则将元素放⼊ hc ,如果存在,则舍去。

以此求得两集合的差集。

#include <iostream>#include <cstdio>#include <malloc.h>using namespace std;/* 定义单链表数据 */typedef char ElemType;typedef struct LNode{ElemType data;struct LNode *next;}LinkList;/* 单链表的初始化 */void InitList(LinkList *&L){L = (LinkList *)malloc(sizeof(LinkList));L->next=NULL;}/* 向单链表中插⼊数据元素 */bool ListInsert(LinkList *&L,int x,char e){int j = 0;LinkList *p = L, *s;while(p!=NULL && j<x-1){p = p->next;j++;}if(p==NULL){return false;}else{s = (LinkList *)malloc(sizeof(LinkList));s->data = e;s->next = p->next;p->next = s;return true;}}/* 输出单链表 */void DispList(LinkList *L){LinkList *p = L->next;while(p!=NULL){printf("%c ",p->data);p = p->next;}printf("\n");}/* 求单链表的长度 */int ListLength(LinkList *L){LinkList *p = L->next;int i = 0;while(p!=NULL){p = p->next;}return i;}/* 查看单链表是否为空 */bool ListEmpty(LinkList *L){return L->next==NULL;}/* 求单链表中某个数据元素值 */bool GetElem(LinkList *L,int i, ElemType &e) {LinkList *p = L;int j = 0;while(p!=NULL && j < i){p=p->next;j++;}if(p==NULL){return false;}else{e = p->data;return true;}}/* 在单链表中查找元素 */int LocateElem(LinkList *L,ElemType e){LinkList *p = L;int i = 0;while(p!=NULL && p->data!=e){p = p->next;i++;}if(p==NULL){return0;}else{return i;}}/* 删除单链表中第 i 个元素*/bool ListDelete(LinkList *&L,int i,ElemType &e) {int j = 0;LinkList *p = L, *q;while(p!=NULL && j < i - 1){p = p->next;j++;}if(p==NULL)return false;else{q = p->next;if(q==NULL)return false;e = q->data;p->next = q->next;free(q);return true;}}/* 删除单链表 */void DestroyList(LinkList *&L){LinkList *p = L;LinkList *q = p->next;while(q!=NULL){p = q;q = p->next;}free(p);}void CreateListR(LinkList *&L,ElemType e[],int n) {InitList(L);int i;for(i = 0;i < n; ++i){if(!LocateElem(L,e[i]))ListInsert(L,i+1,e[i]);}}void InsterSect(LinkList *a,LinkList *b,LinkList *&c) {DestroyList(c);InitList(c);LinkList *p = a->next;int i = 0;while(p!=NULL){if(LocateElem(b,p->data))ListInsert(c,++i,p->data);p = p->next;}}void Subs(LinkList *a,LinkList *b,LinkList *&c){DestroyList(c);InitList(c);LinkList *p = a->next;int i = 0;while(p!=NULL){if(!LocateElem(b,p->data))ListInsert(c,++i,p->data);p = p->next;}}void Union(LinkList *a,LinkList *b,LinkList *&c){InitList(c);LinkList *p = a->next;LinkList *q = b->next;int k = 0;while(p!=NULL && q!=NULL){if(p->data < q->data){ListInsert(c,k+1,p->data);p = p->next;k++;}else if(p->data == q->data){ListInsert(c,k+1,p->data);p = p->next;q = q->next;k++;}else{ListInsert(c,k+1,q->data);q = q->next;k++;}}while(p!=NULL){ListInsert(c,k+1,p->data);p = p->next;k++;}while(q!=NULL){ListInsert(c,k+1,q->data);q = q->next;}///cout<<"hehe"<<endl;}void sort(LinkList *&L){LinkList *p , *pre, *q, *k;InitList(p);int i = 0;char c;while(!ListEmpty(L)){pre = L ->next;c = pre->data;while(pre!=NULL){if(c>=pre->data)c = pre->data;pre = pre->next;}ListInsert(p,++i,c);int tag = LocateElem(L,c);ListDelete(L,tag,c);}L = p;}int main( ){LinkList *ha, *hb, *hc;ElemType a[]={'c','a','e','h'};ElemType b[]={'f','h','b','g','d','a'};printf("集合的运算如下\n");CreateListR(ha,a,4);CreateListR(hb,b,6);printf("原集合 A: "); DispList(ha); printf("原集合 B: "); DispList(hb); sort(ha);sort(hb);printf("有序集合A:"); DispList(ha); printf("有序集合B:"); DispList(hb); Union(ha,hb,hc);printf("集合的并C:"); DispList(hc); InsterSect(ha,hb,hc);printf("集合的交C:"); DispList(hc); Subs(ha,hb,hc);printf("集合的差C:"); DispList(hc); DestroyList(ha);DestroyList(hb);DestroyList(hc);return0;}。

设计两个有序单链表的合并排序算法

设计两个有序单链表的合并排序算法

设计两个有序单链表的合并排序算法有序单链表的合并排序,是一种高效的排序算法,可以在较短的时间内对大量数据进行排序。

这种排序算法的核心在于将两个有序的单链表合并成一个有序的单链表,然后再对整个链表进行排序。

合并排序算法的基本原理是分治法。

将需要排序的数组不断地分解成两个子数组,直到每个子数组只包含一个元素为止。

然后再将这些子数组两两合并,直到整个数组被合并成一个有序的数组为止。

这里介绍两个有序单链表的合并排序算法,它们分别是迭代算法和递归算法。

1. 迭代算法迭代算法是一种通用的算法,它的思路是利用循环结构来重复执行一段相同或相似的代码,从而解决一类问题。

对于有序单链表的合并排序,迭代算法的基本思路是将两个有序单链表的元素依次比较,然后将较小的元素加入到新的链表中,直到两个链表中的元素全部被加入到新链表中为止。

以下是迭代算法的具体实现过程:```// 合并两个有序单链表Node* mergeList(Node* head1, Node* head2) { // 新建一个头结点Node* dummy = new Node(-1);// 定义两个指针,分别指向两个链表的头结点 Node* p = head1;Node* q = head2;// 定义一个指针,指向新链表的最后一个节点 Node* curr = dummy;// 循环比较两个链表中的元素while (p != nullptr && q != nullptr) {if (p->val <= q->val) {curr->next = p;p = p->next;} else {curr->next = q;q = q->next;}curr = curr->next;}// 将剩余的元素加入到新链表中curr->next = p != nullptr ? p : q;// 返回新链表的头结点return dummy->next;}// 归并排序Node* mergeSort(Node* head) {if (head == nullptr || head->next == nullptr) {return head;}// 定义两个指针,一个快指针每次走两步,一个慢指针每次走一步 Node* slow = head;Node* fast = head->next;while (fast != nullptr && fast->next != nullptr) {slow = slow->next;fast = fast->next->next;}// 将链表分成两部分Node* head1 = head;Node* head2 = slow->next;slow->next = nullptr;// 分别对两部分链表进行归并排序head1 = mergeSort(head1);head2 = mergeSort(head2);// 合并两个有序单链表return mergeList(head1, head2);}```2. 递归算法递归算法的思想是将一个大问题分解成若干个小问题,然后逐个解决这些小问题,最终得到大问题的解决方案。

单链表求集合的并、交和差运算

单链表求集合的并、交和差运算

单链表求集合的并、交和差运算单链表是一种常用的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。

在计算机科学中,我们经常需要对集合进行操作,包括求并集、交集和差集。

在本文中,我们将介绍如何使用单链表来实现这些集合操作。

我们需要定义一个单链表的数据结构。

每个节点包含一个数据元素和一个指向下一个节点的指针。

我们可以使用类来实现这个数据结构,例如:```class Node:def __init__(self, data):self.data = dataself.next = Noneclass LinkedList:def __init__(self):self.head = None```接下来,我们需要实现集合的并、交和差运算。

首先是并运算,它将两个集合中的所有元素合并为一个新的集合。

我们可以使用两个指针分别遍历两个链表,将两个链表中的元素逐个比较,并将不重复的元素添加到结果链表中。

具体代码如下:```def union(l1, l2):result = LinkedList()p1 = l1.headp2 = l2.headwhile p1 is not None:result.append(p1.data)p1 = p1.nextwhile p2 is not None:if not result.contains(p2.data):result.append(p2.data)p2 = p2.nextreturn result```接下来是交运算,它将两个集合中共有的元素提取出来组成一个新的集合。

同样地,我们可以使用两个指针分别遍历两个链表,将相同的元素添加到结果链表中。

具体代码如下:```def intersection(l1, l2):result = LinkedList()p1 = l1.headwhile p1 is not None:if l2.contains(p1.data):result.append(p1.data)p1 = p1.nextreturn result```最后是差运算,它将第一个集合中不属于第二个集合的元素提取出来组成一个新的集合。

链表的反转与合并掌握链表反转和合并操作的实现

链表的反转与合并掌握链表反转和合并操作的实现

链表的反转与合并掌握链表反转和合并操作的实现链表是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。

链表的反转和合并是链表操作中常见且重要的操作,在很多编程问题中都有应用。

本文将介绍链表的反转和合并操作的实现方法。

一、链表的反转链表的反转是指将链表中节点的顺序反向排列。

例如,对于链表1→2→3→4→5,反转后的链表为5→4→3→2→1。

实现链表的反转有两种常见的方法:迭代法和递归法。

1. 迭代法迭代法的实现思路是,从链表头节点开始,依次遍历每个节点,将该节点的指针指向前一个节点。

具体步骤如下:1)定义三个指针:当前节点指针cur、前一个节点指针prev、下一个节点指针next。

2)遍历链表,将当前节点的指针指向前一个节点,然后更新prev、cur和next指针的位置。

3)重复上述步骤,直到遍历到链表末尾。

以下是迭代法的实现代码示例(使用Python语言):```pythondef reverse_list(head):prev = Nonecur = headwhile cur:next = cur.nextcur.next = prevprev = curcur = nextreturn prev```2. 递归法递归法的实现思路是,从链表的尾节点开始,依次反转每个节点。

具体步骤如下:1)递归地反转除最后一个节点外的链表。

2)将当前节点的指针指向前一个节点。

3)返回反转后的链表的头节点。

以下是递归法的实现代码示例(使用Python语言):```pythondef reverse_list(head):if not head or not head.next:return headnew_head = reverse_list(head.next)head.next.next = headhead.next = Nonereturn new_head```二、链表的合并链表的合并是指将两个有序链表按照一定的规则合并成一个有序链表。

数据结构C语言版 线性表的单链表存储结构表示和实现

数据结构C语言版 线性表的单链表存储结构表示和实现

#include 〈stdio.h>#include <malloc。

h>#include 〈stdlib.h>/*数据结构C语言版线性表的单链表存储结构表示和实现P28—31编译环境:Dev-C++ 4。

9。

9。

2日期:2011年2月10日*/typedef int ElemType;// 线性表的单链表存储结构typedef struct LNode{ElemType data; //数据域struct LNode *next;//指针域}LNode, *LinkList;// typedef struct LNode *LinkList;// 另一种定义LinkList的方法// 构造一个空的线性表Lint InitList(LinkList *L){/*产生头结点L,并使L指向此头结点,头节点的数据域为空,不放数据的。

void *malloc(size_t)这里对返回值进行强制类型转换了,返回值是指向空类型的指针类型.*/(*L)= (LinkList)malloc(sizeof(struct LNode) );if( !(*L))exit(0);// 存储分配失败(*L)-〉next = NULL;// 指针域为空return 1;}// 销毁线性表L,将包括头结点在内的所有元素释放其存储空间。

int DestroyList(LinkList *L){LinkList q;// 由于单链表的每一个元素是单独分配的,所以要一个一个的进行释放while(*L ){q = (*L)—〉next;free(*L );//释放*L = q;}return 1;}/*将L重置为空表,即将链表中除头结点外的所有元素释放其存储空间,但是将头结点指针域置空,这和销毁有区别哦。

不改变L,所以不需要用指针。

*/int ClearList( LinkList L ){LinkList p,q;p = L—〉next;// p指向第一个结点while( p ) // 没到表尾则继续循环{q = p—>next;free( p );//释放空间p = q;}L—>next = NULL; // 头结点指针域为空,链表成了一个空表return 1;}// 若L为空表(根据头结点L—〉next来判断,为空则是空表),则返回1,// 否则返回0.int ListEmpty(LinkList L){if(L—>next ) // 非空return 0;elsereturn 1;}// 返回L中数据元素个数。

c语言有序单链表的二路归并算法

c语言有序单链表的二路归并算法

c语言有序单链表的二路归并算法C语言有序单链表的二路归并算法一、引言有序单链表是一种常见的数据结构,其中的元素按照一定的顺序排列。

当需要将两个有序单链表合并为一个有序单链表时,可以使用二路归并算法。

本文将介绍使用C语言实现有序单链表的二路归并算法的原理和步骤。

二、算法原理二路归并算法是一种常见的排序算法,它通过将两个有序链表合并为一个有序链表的方式来实现排序。

算法的基本思想是通过比较两个链表中的元素大小,将较小的元素添加到新的链表中,直到将两个链表全部合并为止。

三、算法步骤下面是使用C语言实现有序单链表的二路归并算法的详细步骤:1. 定义两个指针,分别指向两个有序单链表的头结点;2. 创建一个新的链表,用于存储合并后的有序链表;3. 循环比较两个链表中的元素大小,将较小的元素添加到新链表中,并将指针后移;4. 当其中一个链表遍历完毕时,将另一个链表中剩余的元素添加到新链表的末尾;5. 返回新链表的头结点,即为合并后的有序单链表。

四、代码实现下面是使用C语言实现有序单链表的二路归并算法的示例代码:```c#include <stdio.h>#include <stdlib.h>// 定义链表结点typedef struct Node {int data;struct Node* next;} Node;// 创建有序链表Node* createList(int arr[], int size) {Node* head = NULL;Node* tail = NULL;for (int i = 0; i < size; i++) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = arr[i];newNode->next = NULL;if (head == NULL) {head = newNode;tail = newNode;} else {tail->next = newNode;tail = newNode;}}return head;}// 合并两个有序链表Node* mergeList(Node* list1, Node* list2) { if (list1 == NULL) {return list2;}if (list2 == NULL) {return list1;}Node* head = NULL;Node* tail = NULL;while (list1 != NULL && list2 != NULL) { if (list1->data <= list2->data) {if (head == NULL) {head = list1;tail = list1;} else {tail->next = list1;tail = list1;}list1 = list1->next;} else {if (head == NULL) {head = list2;tail = list2;} else {tail->next = list2;tail = list2;}list2 = list2->next;}}if (list1 != NULL) {tail->next = list1;}if (list2 != NULL) {tail->next = list2;}return head;}// 打印链表void printList(Node* head) { Node* p = head;while (p != NULL) {printf("%d ", p->data); p = p->next;}printf("\n");}int main() {int arr1[] = {1, 3, 5};int arr2[] = {2, 4, 6};Node* list1 = createList(arr1, sizeof(arr1) / sizeof(int));Node* list2 = createList(arr2, sizeof(arr2) / sizeof(int));printf("链表1:");printList(list1);printf("链表2:");printList(list2);Node* mergedList = mergeList(list1, list2);printf("合并后的链表:");printList(mergedList);return 0;}```五、算法分析有序单链表的二路归并算法的时间复杂度为O(n),其中n为两个链表的总长度。

链表的合并实验报告

链表的合并实验报告

链表的合并实验报告文稿归稿存档编号:[KKUY-KKIO69-OTM243-OLUI129-G00I-FDQS58-课程设计报告课程设计题目:两个链表的合并专业:软件工程班级:姓名:学号:指导教师:年月日目录1.课程设计的目的及要求2.课程设计的内容(分析和设计)3.算法流程图4.详细步骤5.代码6.显示结果7.课程设计的总结一.课程设计的目的及要求1.目的:实现两个链表的合并2.要求:(1)建立两个链表A和B,链表元素个数分别为m和n个。

(2)假设元素分别为(x1,x2,…xm),和(y1,y2,?…yn)。

把它们合并成一个线形表C,使得:当m>=n时,C=x1,y1,x2,y2,...xn,yn, (x)当n>m时,C=y1,x1,y2,x2,…ym,xm,…,yn输出线形表C(3)用直接插入排序法对C进行升序排序,生成链表D,并输出链表D。

(4)能删除指定单链表中指定位子和指定值的元素。

二.课程设计的内容(分析和设计)1..分析由题目的相关信息可以分析得:首先我们需要建立两个链表AB,A链表的元素个数为m,B链表的元素个数为n;在将A、B链表进行合并,根据m和n的大小关系决定链表C的元素顺序;再将C进行直接插入排序得到一个新的链表D;没次输入完一次链表信息,程序都会对相应的链表进行输入操作以此确保程序输入的数据是你想要输入的数据。

同时当你合并好和排序好后都会进行输出操作。

最后当排序好后你可以指定你所要删除数据的位置来删除你所要删除的数据。

2.设计本次课程设计所需要用到的是关于链表的建立、合并以及直接插入排序的排序算法。

需要先建立两个链表,再将其合并为一个无序链表,最后对这个无序链表进行直接插入排序并将其输出。

难点在于将AB合并为链表C的操作以及对链表C进行直接插入排序的操作和根据用户的意愿可以对链表进行删除的操作。

三.算法流程图四.详细步骤(1)结构体的创建:struct Node(2)链表的创建:struct Node *create()链表的创建。

数据结构 实验一:实现单链表各种基本运算的算法

数据结构 实验一:实现单链表各种基本运算的算法

- 1 -实验一:实现单链表各种基本运算的算法一、 实验目的1、 掌握单链表存储结构的类型定义;2、 实现单链表各种基本运算的算法。

二、 实验环境1、 Windows 操作系统;2、 Visual C++ 6.0三、 实验内容实现单链表各种基本运算的算法。

四、 概要设计1.存储结构的类型定义:Typedef struct LNode{ElemType data;Struct LNode *next;}LinkList;2.单链表示意图:3.项目组成图:4.algo2_2.cpp 的程序文件包含的函数原型及功能:InitList(LinkList *&L) 初始化单链表LDestroyList(LinkList *&L) 释放单链表LListEmpty(LinkList *L)判断单链表L 是否为空表ListLength(LinkList *L)返回单链表L 的元素个数DispList(LinkList *L)输出单链表LGetElem(LinkList *L,int i,ElemType &e)获取单链表L 的第i 个元素LocateElem(LinkList *L,ElemType e)在单链表L 中查找元素eListInsert(LinkList *&L,int i,ElemType e)在单链表L 中的第i 个位置上插入元素e…… head a 1 a 2 a 3 a n ∧ListDelete(LinkList *&L,int i,ElemType &e)在单链表L中删除第i个元素5.exp2_2.cpp程序文件简介:InitList(LinkList *&L) 初始化单链表LDestroyList(LinkList *&L) 释放单链表LListEmpty(LinkList *L) 判断单链表L是否为空表ListLength(LinkList *L) 返回单链表L的元素个数DispList(LinkList *L) 输出单链表LGetElem(LinkList *L,int i,ElemType &e) 获取单链表L的第i个元素LocateElem(LinkList *L,ElemType e) 在单链表L中查找元素eListInsert(LinkList *&L,int i,ElemType e) 在单链表L中的第i个位置上插入元素e ListDelete(LinkList *&L,int i,ElemType &e) 在单链表L中删除第i个元素6.proj2-2的项目的模块结构:在文件algo2-2中,(1)定义单链表结构类型;(2)初始化单链表(3)定义释放单链表的函数(4)定义判断单链表是否为空的函数(5)定义返回单链表元素个数的函数(6)定义输出单链表的函数(7)定义获取第i个元素的函数(8)定义查找元素的函数(9)定义插入元素的函数(10)定义删除元素的函数在文件exp2-2中分别调用algo2-2中所定义的函数7.函数调用关系图:五、详细设计源代码清单见附录。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int data;
struct Node *next;
}Node, *LinkList;
LinkList LA,LB,LC;
void InitList(LinkList *L) //初始化单链表
{
*L=(LinkList)malloc(sizeof(Node));
(*L)->next=NULL;
}
void EnterList(LinkList &L) //尾插法创建单链表。

{
Node *s,*r;
int flag=1,integer;
r=L;
while(flag)
{
scanf("%d",&integer);
if(integer != -1)
{
s=(Node*)malloc(sizeof(Node));
s->data=integer;
r->next=s;
r=s;
}
else
{
flag=0;
r->next=NULL;
}
}
}
void UnionList(LinkList &LA,LinkList &LB,LinkList &LC) {
Node *p,*q,*r,*y;
p=LA->next;
q=LB->next;
r=LC;
while (p)
{
y=(Node*)malloc(sizeof(Node));
y->data=p->data;
r->next=y;
r=y;
p=p->next;
}
while (q)
{
y=(Node*)malloc(sizeof(Node));
y->data=q->data;
r->next=y;
r=y;
q=q->next;
}
r->next=NULL;
}
void DeSameList(LinkList *LC)//删除c表的相同元素。

{
Node *p,*q,*r;
for(p=(*LC)->next;p!=NULL;p=p->next)
for(q=p->next,r=p;q!=NULL;q=q->next)
if(q->data==p->data)
{
r->next=q->next;
free(q);
q=r;
}
else
r=r->next;
}
void MergeList(LinkList *LA,LinkList *LB,LinkList *LC) { /*归并算法*/
Node *p,*q,*r;
p=(*LA)->next;
q=(*LB)->next;
*LC=*LA;
(*LC)->next=NULL;
r=*LC;
while(p != NULL && q !=NULL)
{
if(p->data <= q->data)
{
r->next=p;
r=p;
p=p->next;
}
else
{
r->next=q;
r=q;
q=q->next;
}
r->next=p?p:q;
}
free(*LB);
}
void printList(LinkList *L) {
Node *p=(*L)->next;
while(p!=NULL)
{
printf("%3d",p->data);
p=p->next;
}
printf("\n");
}
void DestroyList(LinkList *L) //清空链表
{ Node *p,*r; p=*L;
while(!p->next)
{ r=p;
p=p->next;
free(r); }
printf("删除成功!"); }
void first()
{
printf("请输入顺序表LA(当输入-1时结束):\n");
InitList(&LA);
EnterList(LA);
printf("请输入顺序表LB(当输入-1时结束):\n");
InitList(&LB);
EnterList(LB);
printf("表LA和表LB合并后表LC为:");
InitList(&LC);
UnionList(LA,LB,LC);
DeSameList(&LC);
printList(&LC);
printf("表LA和表LB归并后表LC为:");
MergeList(&LA,&LB,&LC);
printList(&LC);
}
void decide()
{int s;printf("1重新开始\n2退出\n");
scanf("%d",&s);
if(s==1){system("cls");
first();}
else if(s==2)exit(0);
else printf("Error!!! try again,!");
decide();
}
void main() {
first ();
decide(); }。

相关文档
最新文档