合并有序表 (顺序存储 和 链式存储 方式实现)

2024-04-17 01:28

本文主要是介绍合并有序表 (顺序存储 和 链式存储 方式实现),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

代码详细解析:

合并有序表文章浏览阅读1.4k次,点赞6次,收藏7次。●假设有两个有序表 LA和LB , 将他们合并成一个有序表LC●要求不破坏原有的表 LA和 LB构思:把这两个表, 合成一个有序表 , 不是简简单单吗?就算是把他们先遍历不按顺序插入到表 C里面 , 然后再排序 ,就行了,这个的确是最笨的办法 , 但是也能完成题目上 ,给出的是这两个表都是有序表 , 所以就省去了 ,我们遍历所有节点排序的麻烦 , 那我们也不能拿一个表进行强行插入, 题目上也不允许,_请设计一个能够将有序顺序表la,lb进行合并的算法,要求合并后的顺序表lc依然有序。https://blog.csdn.net/qq_57484399/article/details/127171775

版本更新日志

V1.0 : 顺序存储和链式存储, 初步利用算法库进行实现

目录

版本更新日志

V1.0

一 . 合并顺序存储有序表

 合并功能函数:

 用到的算法库:

list.h

list.cpp

main.cpp测试函数

运行演示结果:

二 . 合并链式存储有序表

合并功能函数:

用到的算法库:

singlelist.h

singlelist.cpp

main.cpp测试函数

运行结果演示:


V1.0

一 . 合并顺序存储有序表

 合并功能函数:

/**************************************************
函数名: Merged_ordered_list
功  能: 合并数组顺序表
参  数: SqList *LA,SqList *LB,SqList *&LC:把LA和LB合并成LC
注 意: ① 记得给LC长度赋值, 避免遍历时溢出
返回值:  无
**************************************************/
void Merged_ordered_list(SqList *LA, SqList *LB, SqList *&LC)
{int locationA = 0;int locationB = 0;int locationC = 0;LC = (SqList*)malloc(sizeof(SqList));//LA和LB均未达到末尾,选择小的加入while(locationA < LA->length && locationB < LB->length){if(LA->data[locationA] < LB->data[locationB]){LC->data[locationC] = LA->data[locationA];locationA++;locationC++;}else{LC->data[locationC] = LB->data[locationB];locationB++;locationC++;}}//下面多两种情况其一或者没有//经过上一轮循环插入,LB已经扫描插入完了,//LA尚未扫描插入完,将LA其余元素插入到Lc中while(locationA < LA->length){LC->data[locationC] = LA->data[locationA];locationA++;locationC++;}//经过上一轮循环插入,LA已经扫描插入完了,//LB尚未扫描插入完,将LB其余元素插入到LC中while(locationB < LB->length){LC->data[locationC] = LB->data[locationB];locationB++;locationC++;}LC->length = locationC;   // ①
}

 用到的算法库:

list.h

#ifndef LIST_H_INCLUDE
#define LIST_H_INCLUDE#include <malloc.h>#define MaxSize   100typedef int ElemType;	//自定义类型typedef struct			//自定义结构体
{ElemType data[MaxSize];int length;
}SqList;//①用数组创建线性表
void CreateList(SqList *&L, ElemType a[],int n);
//②初始化线性表
void InitList(SqList *&L);
//③输出线性表
void DispalyList(SqList *L);
//④判断是否为空表
bool ListEmpty(SqList *L);
//⑤销毁线性表
void DestroyList(SqList *&L);//⑥ 求线性表的长度
int ListLength(SqList *L);//⑦求某个位置的数据元素值GetElem(L,i,e)
bool GetElem(SqList *L,int i, ElemType &e);//⑧ 元素 e 在 L中的序号(逻辑序号 1~n)
int LocateElement(ElemType element, SqList *L);//⑨ L中 第 i 位, 插入 e, ListInsert(L,i,e)
bool ListInsert(SqList *&L,int i, ElemType e);//⑩ 删除 L 中特定位置 i 的元素 e,  ListDelete(L,i,e)
bool ListDelete(SqList *&L, int i, ElemType &e);#endif

list.cpp

#include <stdio.h>
#include "list.h"/**************************************************
①函数名: CreateList
功  能: 用数组构建顺序表
参  数: ①SqList *&L:传入的线性表 ②ElemType a[]:使用的数组③int n: 线性表的长度(n < Maxsize)
返回值: 无
**************************************************/
void CreateList(SqList *&L, ElemType a[],int n)
{int i;//分配空间L = (SqList*)malloc(sizeof(SqList));for(i = 0; i<n; i++){L->data[i] = a[i];}L->length = n;
}/**************************************************
②函数名: InitList
功  能: 初始化线性表,重新分配空间,长度清成零
参  数: ①SqList *&L:要进行初始化的线性表
返回值:  无
**************************************************/void InitList(SqList *&L)
{L = (SqList*)malloc(sizeof(SqList)); //既然初始化了,直接重新分配空间L->length = 0;}/**************************************************
③函数名: 		DispalyList
功  能: 	输出数组线性表到控制台
使用场景: 	调试输出专用
参  数: 	①SqList *L:所需展示的顺序表
返回值:		void
**************************************************/
void DispalyList(SqList *L)
{if(L->length == 0) return;for(int i = 0; i< L->length; i++){printf("%d ",L->data[i]);}printf("\n");
}/**************************************************
④函数名: 	ListEmpty
功  能: 判断顺序表是否为空
参  数: ① SqList *L: 需要判断的顺序表
返回值: (bool类型)  是空表 ? 返回1  : 不是返回0
**************************************************/
bool ListEmpty(SqList *L)
{return(L->length == 0);
}/**************************************************
⑤函数名 : DestroyList
功  能: 释放顺序表空间
参  数: ① SqList *&L: 所需释放的线性表的指针地址
注  意: (1)
返回值:  无
**************************************************/
void DestroyList(SqList *&L) //(1)注意是指针地址
{//c语言, 直接freefree(L);}/**************************************************
⑥函数名:ListLength
功  能: 返回顺序表长度
参  数: ① SqList *L:传入顺序表的名字
返回值:  int: 线性表长度值
**************************************************/
int ListLength(SqList *L)
{return (L->length);
}/**************************************************
⑦函数名:GetElem
功  能: 取线性表数组内,某个序号的元素值,并返回
参  数: ①SqList *L: 要取的线性表 ②int i:要取的序号(逻辑需要 1-n)③ElemType &e:返回到特定位置
注意:①合法性判断 ②   需要把逻辑(1~n)变成物理序号(0~n-1)
返回值:	bool:是否获取成功
**************************************************/
bool GetElem(SqList *L,int i, ElemType &e)
{if(i<1 || i>L->length)//①{return false;}e = L->data[i-1];  //②return true;
}/**************************************************
⑧函数名: LocateElement
功  能: 查找特定元素值,在线性表中的位置(1~n)
参  数: ①ElemType element: 特定元素值 ② SqList *L:被查的线性表
返回值: int: 位置信息 (0没找到, 1~n, 即为位置)
**************************************************/
int LocateElement(ElemType element, SqList *L)
{int i = 0;while(i < L->length && L->data[i] != element) i++;//如果 i跳出后, i范围超过 L->length,则 没找到if(i >= L->length) return 0;else   return i+1;}
/**************************************************
函数名: ListInsert
功  能: 把 e 插到到线性表 L 的第 i(逻辑序号) 个位置
参  数: (1)SqList *&L: 线性表L (2)int i: 插入到的逻辑位置(3) ElemType e:要插入的元素值
注意:① 可插入的位置逻辑序号为1~L->length+1②得出 j最后是等于 i+1, 所以j的范围是 j>i③从 j=L->length得出 , data[j] = data[j-1],从而确定整体范围
返回值: bool:是否插入完成
**************************************************/
bool ListInsert(SqList *&L,int i, ElemType e)
{int j;if(i<1 || i>L->length+1)    //①return false;i--;        //将顺序表的逻辑序号转化为物理序号for(j = L->length; j > i; j--)  //② data[i+1] = data[i] => j = i+1{//③ data[i]~data[L->length-1]整体后移到data[i+1]~data[L->length]L->data[j] = L->data[j-1];}L->data[i] = e;     //插入元素eL->length++;        //顺序表插入增1return true;       //成功插入返回true}/**************************************************
函数名: ListDelete
功  能: 删除顺序表特定位置的元素
参  数: (1)SqList *&L:被删的顺序表 (2)int i:位置(3)ElemType &e:删掉的值
注 意:  ① 思路是整体前移,所以确定初始值i,然后定公式,看临界定 范围② 最后一个是 data[L->length-2] = data[L->length-1],得出 j = L->length-2
返回值: bool:是否删除成功? true : false
**************************************************/
bool ListDelete(SqList *&L, int i, ElemType &e)
{int j;if(i < 1 || i > L->length) return false;i--;    //把逻辑序号转为物理序号e = L->data[i]; //将要删除的元素存储for(j = i;j < L->length-1; j++)//①将data[i...n-1]整体前移{//② data[i+1]~data[L->length-1] => data[i] ~ data[L->length-2]L->data[j] = L->data[j+1];}L->length--;    //顺序表长度减去1return true;
}

main.cpp测试函数

#include "list.h"
#include "stdio.h"
/**************************************************
函数名: Merged_ordered_list
功  能: 合并数组顺序表
参  数: SqList *LA,SqList *LB,SqList *&LC:把LA和LB合并成LC
注 意: ① 记得给LC长度赋值, 避免遍历时溢出
返回值:  无
**************************************************/
void Merged_ordered_list(SqList *LA, SqList *LB, SqList *&LC)
{int locationA = 0;int locationB = 0;int locationC = 0;LC = (SqList*)malloc(sizeof(SqList));//LA和LB均未达到末尾,选择小的加入while(locationA < LA->length && locationB < LB->length){if(LA->data[locationA] < LB->data[locationB]){LC->data[locationC] = LA->data[locationA];locationA++;locationC++;}else{LC->data[locationC] = LB->data[locationB];locationB++;locationC++;}}//下面多两种情况其一或者没有//经过上一轮循环插入,LB已经扫描插入完了,//LA尚未扫描插入完,将LA其余元素插入到Lc中while(locationA < LA->length){LC->data[locationC] = LA->data[locationA];locationA++;locationC++;}//经过上一轮循环插入,LA已经扫描插入完了,//LB尚未扫描插入完,将LB其余元素插入到LC中while(locationB < LB->length){LC->data[locationC] = LB->data[locationB];locationB++;locationC++;}LC->length = locationC;   // ①
}int main()
{SqList *LA,*LB,*LC;ElemType A[3] = {1,3,5};ElemType B[4] = {2,4,8,10};CreateList(LA,A,3);printf("A展示:\n");DispalyList(LA);CreateList(LB,B,4);printf("B展示:\n");DispalyList(LB);printf("A+B合并排序成C展示:\n");Merged_ordered_list(LA,LB,LC);DispalyList(LC);return 0;
}

运行演示结果:

二 . 合并链式存储有序表

合并功能函数:

/**************************************************
函数名: Union_order_singlelist
功  能: 合并两个有序单链表为一个有序单链表
参  数: LinkList *LA,LinkList *LB, LinkList *&LC:LA和LB合并为LC
注  意: ①②③结束条件, 是遍历节点为空
返回值: 无
**************************************************/
void Union_order_singlelist(LinkList *LA,LinkList *LB, LinkList *&LC)
{
//    int counter = 0;//定义遍历LA和LB的指针LinkList *visit_A = LA->next;LinkList *visit_B = LB->next;//定位LC尾指针LinkList *tail_C;LinkList *newNode;//为LC头结点分配空间LC = (LinkList*)malloc(sizeof(LinkList));tail_C = LC;LC->next = NULL;//轮询遍历LA和LB,数据插入LCwhile(visit_A != NULL && visit_B != NULL) //①{//为LC新节点分配空间newNode = (LinkList*)malloc(sizeof(LinkList));if(visit_A->data < visit_B->data){newNode->data = visit_A->data;//处理完后,后移,为后面做准备visit_A = visit_A->next;//对LC进行尾插法tail_C->next = newNode;tail_C = newNode;   //涉及指针覆盖,顺序不可调换
//            counter++;
//            printf("\n第%d个数是 %d \n",counter,newNode->data);}else{newNode->data = visit_B->data;//处理完后,后移,为后面做准备visit_B = visit_B->next;//对LC进行尾插法tail_C->next = newNode;tail_C = newNode;//涉及指针覆盖,顺序不可调换//            counter++;
//            printf("\n第%d个数是 %d \n",counter,newNode->data);}}//经过上一步的交替插入,要么两个表交替插入完了,要么是下面两者之一//LB已经扫描插入完了, LA尚未扫描插入完 , 将其余元素插入到 Lc中while(visit_A != NULL)//③{//为LC新节点分配空间newNode = (LinkList*)malloc(sizeof(LinkList));newNode->data = visit_A->data;//处理完后,后移,为后面做准备visit_A = visit_A->next;//对LC进行尾插法tail_C->next = newNode;tail_C = newNode;   //涉及指针覆盖,顺序不可调换//        counter++;
//        printf("\n第%d个数是 %d \n",counter,newNode->data);}while(visit_B != NULL) //③{//为LC新节点分配空间newNode = (LinkList*)malloc(sizeof(LinkList));newNode->data = visit_B->data;//处理完后,后移,为后面做准备visit_B = visit_B->next;//对LC进行尾插法tail_C->next = newNode;tail_C = newNode;//涉及指针覆盖,顺序不可调换
//        counter++;
//        printf("\n第%d个数是 %d \n",counter,newNode->data);}//尾结点置空,善后工作tail_C->next = NULL;
}

用到的算法库:

singlelist.h

#ifndef SINGLELIST_H_INCLUDE
#define SINGLELIST_H_INCLUDE#include <stdio.h>
#include <malloc.h>typedef int ElemType;   //定义单链表节点类型typedef struct LNode
{ElemType data;struct LNode *next; //指向后继节点}LinkList;
//①头插法建立单链表
void CreatList_Head(LinkList *&L, ElemType Array_used[], int Array_number);
//②尾插法建立单链表
void CreatList_Tail(LinkList *&L, ElemType Array_used[], int Array_number);
//③输出单链表
void DisplayLinkList(LinkList *L);
//④销毁单链表
void DestroyLinkList(LinkList *&L);
//⑤ 初始化线性表
void InitLinkList(LinkList *&L);
//⑥ 判断线性表是否为空表
bool LinkListEmpty(LinkList *L);
//⑦ 返回单链表L中数据节点的个数
int LinkListLength(LinkList *L);
//⑧ 求线性表L中指定位置的某个数据元素
bool SpecificLocate_Value(LinkList *L,int location, ElemType &value);
//⑨ 按元素值查找特定元素的位置
int SpecificValue_Location(LinkList *L, ElemType value);
//⑩ 把元素插入到特定位置
bool LinkList_InsertElement(LinkList *&L, int location, ElemType &value);
//(11) 删除特定位置的节点元素
bool LinkList_Delete_Location(LinkList *&L,int location, ElemType &value);
//(12)单链表删除其中其最大节点元素
bool  DeleteMaxNode(LinkList *&L);
//(13)对单链表中元素进行排序(至少有2个数据节点)
bool LinkList_sorting(LinkList *&L);
#endif // SINGLELIST_H_INCLUDE

singlelist.cpp

#include "singlelist.h"/**************************************************
①函数名: CreatList_Head
功  能: 头插法建立单链表
参  数: (1)LinkList *&L: 传入的单链表指针地址(2)ElemType Array_used[]:要用来建表的数组(3)int Array_number: 数组的长度
返回值:    无
**************************************************/
void CreatList_Head(LinkList *&L, ElemType Array_used[], int Array_number)
{int counter;LinkList *newnode;L = (LinkList *)malloc(sizeof(LinkList)); //创建头结点L->next = NULL;for(counter = 0; counter < Array_number; counter++){newnode = (LinkList *)malloc(sizeof(LinkList));  //创建新节点newnode->data = Array_used[counter];newnode->next = L->next;         //将newnode插在原开始结点之前,头结点之后L->next = newnode;}
}
/**************************************************
②函数名: CreatList_Tail
功  能: 尾插法建立单链表
参  数: (1)LinkList *&L: 传入的单链表指针地址(2)ElemType Array_used[]:要用来建表的数组(3)int Array_number:数组的长度
返回值:   无
**************************************************/
void CreatList_Tail(LinkList *&L, ElemType Array_used[], int Array_number)
{int counter;LinkList *newnode,*tailnode;L = (LinkList *)malloc(sizeof(LinkList));//创建头结点L->next = NULL;tailnode = L;       //尾结点tailnode始终指向终端结点,开始指向头结点for(counter = 0; counter < Array_number; counter++){newnode = (LinkList *)malloc(sizeof(LinkList)); //创建新节点newnode->data = Array_used[counter];tailnode->next = newnode;   //将新节点插入到尾结点之后tailnode = newnode;         //更新尾结点}tailnode->next = NULL;          //终端结点next域置空
}/**************************************************
③函数名: DisplayLinkList
功  能: 输出单链表
参  数: (1)LinkList *L:将要输出的单链表
返回值: 无
**************************************************/void DisplayLinkList(LinkList *L)
{LinkList *shownode;shownode = L->next;while(shownode != NULL){printf("%d",shownode->data);printf(" ");shownode = shownode->next;        //一直遍历,直到指向尾->newt = NULL}printf("\n");
}
/**************************************************
④函数名: DestroyLinkList
功  能: 销毁单链表
参  数: (1)LinkList *&L:要销毁的单链表
注意:① 等到指引下一个节点的指针为Null时就跳出,避免出现野指针,此时再销毁destroyNode② 避免断开联系,记录 销毁节点的下一个节点
返回值: 无
**************************************************/
void DestroyLinkList(LinkList *&L)
{LinkList *destoryNode,*nextNode;destoryNode = L;nextNode = destoryNode->next;while(nextNode != NULL)        //①{free(destoryNode);destoryNode = nextNode;nextNode = destoryNode->next;   //②}free(destoryNode);
}
/**************************************************
⑤函数名: InitLinkList
功  能: 初始化单链表
参  数: LinkList *&L:要被初始化的链表指针地址
返回值: 无
**************************************************/
void InitLinkList(LinkList *&L)
{L = (LinkList *)malloc(sizeof(LinkList));//创建头结点L->next = NULL;
}
/**************************************************
⑥函数名: LinkListEmpty
功  能: 判断单链表是否为空
参  数: (1)LinkList *L:要判断的单链表
返回值: bool: 是否为空? treu:false
**************************************************/
bool LinkListEmpty(LinkList *L)
{return (L->next == NULL);
}/**************************************************
⑦函数名: LinkListLength
功  能: 返回单链表L中数据节点的个数
参  数: LinkList *L:要计算的数据节点
返回值: int: 线性表数据节点个数值
**************************************************/
int LinkListLength(LinkList *L)
{int counter = 0;LinkList *nowNode = L;while(nowNode->next != NULL){counter++;nowNode = nowNode->next;}return counter;
}/**************************************************
⑧函数名: GetLocateValue
功  能: 求特定位置的数据元素值
参  数: (1)LinkList *L:要找的单链表(2)int location:所要找的位置(3)ElemType &value: 传递回所要找的值
注意: ① 判断跳出的时候, 是查找成功, 还是抵达末尾② counter == 要找到序号,则跳出,所以counter < location  ,nowNode指向的节点为空,则到末尾,则跳出③④ 这两条语句, 所指向的序号和节点, 是同步的, 位置到或者此节点为空,则跳出
返回值: bool: 是否查找成功? true:false
**************************************************/
bool SpecificLocate_Value(LinkList *L,int location, ElemType &value)
{int counter = 0;LinkList *nowNode = L;while(counter < location && nowNode != NULL)//②{counter++;          //③  当前计数的节点nowNode = nowNode->next;//④当前遍历到的节点}if(nowNode == NULL)                //①{return false;}else{value = nowNode->data;return true;}}/**************************************************
⑨函数名:SpecificValue_Location
功  能: 查找特定数据值的节点,并返回其位置
参  数: (1)LinkList *L: 被查找的单链表(2)ElemType e:
注  意:  ①从头结点后的第一个节点开始找②while循环内的两条语句是同步指向的③当nowNode为空时(到达末尾仍未找到), counter作废④当nowNode不为空时,跳出时, counter表示所指向节点存在,并符合所需
返回值:
**************************************************/
int SpecificValue_Location(LinkList *L, ElemType value)
{int counter = 1;LinkList *nowNode = L->next;    //①while(nowNode != NULL && nowNode->data != value){nowNode = nowNode->next;counter++;                     //②}if(nowNode == NULL)           //③{return 0;}else                    //④{return counter;}}
/**************************************************
⑩函数名: LinkList_InsertElement
功  能: 在单链表特定位置插入节点
参  数: (1)LinkList *&L:要插入的单链表(2)int location:要插入的位置(3) ElemType &value:插入的数据
思路:    先在单链表L中,找到第 i-1个节点(不算头结点),若存在这样的节点,将值为value的节点 插入到其后面
注意:    ① 计数器和 nowNode是同步往后移动(从L->next开始算第一个节点),直到 找到counter = location-1,②此时 nowNode不为空,则此时nowNode指向要插入位置的 前一个节点③ 覆盖指针前, 牢记 nowNode->next里面存放的是后继节点信息,所以要先处理newNode->next = nowNode->next;然后我们才能再把 nowNode->next指向新节点 newNode
返回值: bool: 是否存在第i-1个节点,并插入成功? true : false
**************************************************/
bool LinkList_InsertElement(LinkList *&L, int location, ElemType &value)
{int counter = 0;LinkList *nowNode = L;LinkList *newNode;while((counter < (location-1)) && (nowNode != NULL)) //①{counter++;nowNode = nowNode->next;}if(nowNode == NULL)//②{return false;}else{newNode = (LinkList *)malloc(sizeof(LinkList));newNode->data = value;newNode->next = nowNode->next;//③nowNode->next = newNode;return true;}
}
/**************************************************
(11)函数名: LinkList_Delete_Location
功  能: 删除特定位置的节点元素
参  数: (1)LinkList *&L:被删除的单链表 (2)int location:特定位置(3) ElemType &value:被删除的元素值
思路:    找到第location-1个元素, 存储第locataion个元素值(判断null),然后free链接 location-1 和 location+1
注意:    ① counter和指针节点是同步的,要么找到location-1个节点,要么到末尾② 虽然可能找到location-1个元素,其可能是最后一个元素,从而导致删除失败需要判断一下,deleteNode是否为空,才能得出是否任务成功③ 指针覆盖还是老生常谈,先存储一下deleteNode(方便free),然后指针交替,然后free
返回值:  bool: 是否删除成功? true:false
**************************************************/
bool LinkList_Delete_Location(LinkList *&L,int location, ElemType &value)
{int counter = 0;LinkList *nowNode = L;LinkList *deleteNode;while(counter < (location-1) && nowNode != NULL)   //①{counter++;nowNode = nowNode->next;}if(nowNode == NULL){return false;}else{deleteNode = nowNode->next;if(deleteNode == NULL)    //②{return false;}value = deleteNode->data;nowNode->next = deleteNode->next;  //③free(deleteNode);return true;}
}/**************************************************
(12)函数名: DeleteMaxNode
功  能: 删除单链表中最大的一个节点
参  数: (1)LinkList *&L:要删除节点的单链表
思路: 四个指针, 最大指针,最大指针前一个节点目前遍历的指针,遍历指针的前一个节点, 边比较,边替换,边遍历
注意:①避免只有一个头结点,造成空指针替换异常②③ 顺序不能变,因为③跳出的时候, 会利用到while的非空条件,避免对比的时候, 出现野指针,直到为空时,即可直接跳出,非空则比较替换
返回值:是否删除成功 ? true:false
**************************************************/
bool   DeleteMaxNode(LinkList *&L)
{LinkList *nowNode,*preNode;LinkList *maxNode,*preMaxNode;nowNode = L->next;preNode = L;maxNode = nowNode;preMaxNode = preNode;if(nowNode == NULL) //①{return false;}while(nowNode != NULL) //直到末尾{if(nowNode->data > maxNode->data)   //②{maxNode = nowNode;preMaxNode = preNode;}preNode = nowNode;       //接着走下一个节点nowNode = nowNode->next;   //③}preMaxNode->next = maxNode->next;free(maxNode);return true;
}/**************************************************
(13)函数名:LinkList_sorting
功  能:对单链表中元素进行排序(至少有2个数据节点)
参  数:LinkList *&L:要进行排序的单链表
注意: ① 空表,或者只有一个数据节点,则不需要排序,返回false② 开始节点必须是头结点,因为我们会用到start_compare->next,③ 把数据节点(第二个数据节点及以后)和原始链表(头结点+一个数据节点)④ 在有序表中,一直找到比前一个节点大,比后一个节点小的空挡,所以时刻对比start_compare->next->data, 并且start_compare->next不能为空(为空代表到达末尾,交替空指针)⑤ 顺序不能变, 避免丢失有序表后续信息(指针覆盖的一句话)
详细链接:https://blog.csdn.net/qq_57484399/article/details/127141307
返回值:bool: 是否符合排序标准,并排序成功  ? true: false
**************************************************/
bool LinkList_sorting(LinkList *&L)
{LinkList *compare,*start_compare,*Remaining_node;if(L->next == NULL || L->next->next == NULL)//①保证至少有2个数据节点{return false;}compare = L->next->next;start_compare = L;  //②开始节点必须是头结点Remaining_node = compare->next;L->next->next = NULL; //③把数据节点(第二个数据节点及以后)和原始链表(头结点+一个数据节点)while(compare != NULL){Remaining_node = compare->next;start_compare = L;while((start_compare->next != NULL) && (compare->data > start_compare->next->data)){start_compare = start_compare->next;} //④compare->next = start_compare->next;start_compare->next = compare;     //⑤compare = Remaining_node;}return true;}

main.cpp测试函数

#include <stdio.h>
#include "singlelist.h"/*****************************************
功  能: 把两个有序单链表合并成一个有序单链表
编程人: 王涛
时  间: 2024.4.16
版  本: V1.0
思路://定义遍历LA和LB的指针//轮询遍历LA和LB,数据插入LC//收尾,LA或LB没遍历完,插入到LC
******************************************//**************************************************
函数名: Union_order_singlelist
功  能: 合并两个有序单链表为一个有序单链表
参  数: LinkList *LA,LinkList *LB, LinkList *&LC:LA和LB合并为LC
注  意: ①②③结束条件, 是遍历节点为空
返回值: 无
**************************************************/
void Union_order_singlelist(LinkList *LA,LinkList *LB, LinkList *&LC)
{
//    int counter = 0;//定义遍历LA和LB的指针LinkList *visit_A = LA->next;LinkList *visit_B = LB->next;//定位LC尾指针LinkList *tail_C;LinkList *newNode;//为LC头结点分配空间LC = (LinkList*)malloc(sizeof(LinkList));tail_C = LC;LC->next = NULL;//轮询遍历LA和LB,数据插入LCwhile(visit_A != NULL && visit_B != NULL) //①{//为LC新节点分配空间newNode = (LinkList*)malloc(sizeof(LinkList));if(visit_A->data < visit_B->data){newNode->data = visit_A->data;//处理完后,后移,为后面做准备visit_A = visit_A->next;//对LC进行尾插法tail_C->next = newNode;tail_C = newNode;   //涉及指针覆盖,顺序不可调换
//            counter++;
//            printf("\n第%d个数是 %d \n",counter,newNode->data);}else{newNode->data = visit_B->data;//处理完后,后移,为后面做准备visit_B = visit_B->next;//对LC进行尾插法tail_C->next = newNode;tail_C = newNode;//涉及指针覆盖,顺序不可调换//            counter++;
//            printf("\n第%d个数是 %d \n",counter,newNode->data);}}//经过上一步的交替插入,要么两个表交替插入完了,要么是下面两者之一//LB已经扫描插入完了, LA尚未扫描插入完 , 将其余元素插入到 Lc中while(visit_A != NULL)//③{//为LC新节点分配空间newNode = (LinkList*)malloc(sizeof(LinkList));newNode->data = visit_A->data;//处理完后,后移,为后面做准备visit_A = visit_A->next;//对LC进行尾插法tail_C->next = newNode;tail_C = newNode;   //涉及指针覆盖,顺序不可调换//        counter++;
//        printf("\n第%d个数是 %d \n",counter,newNode->data);}while(visit_B != NULL) //③{//为LC新节点分配空间newNode = (LinkList*)malloc(sizeof(LinkList));newNode->data = visit_B->data;//处理完后,后移,为后面做准备visit_B = visit_B->next;//对LC进行尾插法tail_C->next = newNode;tail_C = newNode;//涉及指针覆盖,顺序不可调换
//        counter++;
//        printf("\n第%d个数是 %d \n",counter,newNode->data);}//尾结点置空,善后工作tail_C->next = NULL;
}int main()
{LinkList *LA,*LB,*LC;//定义数组ElemType test_A[8] = {9,33,5,77,8,22,11,6};ElemType test_B[5] = {12,30,19,25,66};//尾插法建立单链表CreatList_Tail(LA,test_A,8);//输出展示printf("\nLA:\n");DisplayLinkList(LA);//把单链表变有序if(LinkList_sorting(LA)){printf("\n成功排序LA排序%d个数:\n",LinkListLength(LA));DisplayLinkList(LA);}CreatList_Tail(LB,test_B,5);printf("\nLB:\n");DisplayLinkList(LB);if(LinkList_sorting(LB)){printf("\n成功排序LB排序%d个数:\n",LinkListLength(LB));DisplayLinkList(LB);}Union_order_singlelist(LA,LB,LC);printf("\n成功合并LA和LB并排序%d个数为LC:\n",LinkListLength(LC));DisplayLinkList(LC);//释放空间DestroyLinkList(LA);DestroyLinkList(LB);DestroyLinkList(LC);return 0;
}

运行结果演示:

这篇关于合并有序表 (顺序存储 和 链式存储 方式实现)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/910438

相关文章

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount