數據庫結構筆記--線性表的合並
線性表合並
問題描述:

問題分析:
可以利用兩個線性表 LA 和 LB 分別表示集合A和 B (即線性表中的數據元素為集合中的成
員), 這樣只需擴大線性表 LA, 將存在千 LB-中而不存在千 LA 中的數據元素插入到 LA 中去。
只要從 LB 中依次取得每個數據元素, 並依值在 LA 中進行查訪, 若不存在, 則插入之。
【算法步驟】
-
分別獲取 LA表長 m和 LB 表長n。
-
從 LB 中第 1 個數據元素開始, 循環n次執行以下操作:
• 從 LB 中查找第 i 個數據元素賦給 e;
• 在 LA 中查找元素 e, 如果不存在, 則將 e 插在表LA 的最后。
c語言實現:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct node{
int number;
struct node * next;
}Node,*LinkList;
//創建單鏈表,尾插法
LinkList initLink(){
LinkList head=(LinkList)malloc(sizeof(Node));//創建頭節點
LinkList temp=head;//聲明一個指針,用於遍歷
LinkList p;
printf("鏈表初始化,輸入0結束:\n");
int num;
while(1){
scanf("%d",&num);
fflush(stdin); //清空緩存
if (num==0) return head;//判斷是否停止
p =(LinkList)malloc(sizeof(Node));
p->number=num;
p->next=NULL;
temp->next=p;
temp=p;
}
}
//遍歷列表
void travelList(LinkList pNode){
LinkList temp=pNode;//用於遍歷
int num;
while(temp->next){
temp=temp->next;
num=temp->number;
printf("%d\n",num);
}
}
//獲取表長
int lenList(LinkList pNode){
LinkList temp=pNode;
int len=0;
while(temp->next){
temp=temp->next;
len++;
}
return len;
}
//查找函數,判斷元素是否在鏈表中
bool search(LinkList pNode,int elem){
LinkList temp=pNode;
bool isExist=false;
while(temp->next){
temp=temp->next;
if (elem==temp->number) isExist=true;
}
return isExist;
}
//在鏈表尾部插入數據
void insert(LinkList pNode,int elem){
LinkList target,p;
for(target=pNode;target->next!=NULL;target=target->next) ;//找到最后一個節點
p=(LinkList)malloc(sizeof(Node));
p->next=NULL;
p->number=elem;
target->next=p;
}
//合並鏈表
void mergeList(LinkList La, LinkList Lb){
//用到兩次遍歷。一次時遍歷lb表,取出每個元素然后和a表進行查找是否存在
//需要用一個查找函數
LinkList temp=Lb;
int elem;
while(temp->next){
temp=temp->next;
elem=temp->number;
if (search(La,elem)){//如果此元素存在La里
continue;
}else{//如果不存在,則進行連表插入
//再鏈表la尾部插入數據
insert(La,elem);
}
}
}
int main(){
Node *La,*Lb;//兩個鏈表
printf("初始化la\n");
La=initLink();
printf("初始化后的鏈表La\n");
travelList(La);
n=lenList(La);
printf("La鏈表長度為:%d\n",n);
printf("初始化lb\n");
Lb=initLink();
printf("初始化后的鏈表Lb\n");
travelList(Lb);
n=lenList(Lb);
printf("Lb鏈表長度為:%d\n",n);
mergeList(La,Lb);
printf("合並后的來鏈表為\n");
travelList(La);
}
調試結果:

有序表的合並
鏈式有序表合並
問題分析:
假設頭指針為LA和LB的單鏈表分別為線性表LA和LB的存儲結構,現要歸並LA和LB
得到單鏈表 LC。因為鏈表結點之間的關系是通過指針指向建立起來的,所以用鏈表進行合並不
需要另外開辟存儲空間,可以直接利用原來兩個表的存儲空間,合並過程中只需把LA和LB兩
個表中的結點重新進行鏈接即可。
【算法步驟】
-
指針 pa和 pb 初始化,分別指向LA和LB的第一個結點。
-
LC的結點取值為LA的頭結點。
-
指針 pc初始化,指向LC的頭結點。
-
當指針 pa 和 pb 均未到達相應表尾時, 則依次比較 pa 和 pb 所指向的元素值, 從 LA 或
LB 中 "摘取“ 元素值較小的結點插入到 LC 的最后。
-
將非空表的剩余段插入到 pc 所指結點之后。
-
釋放 LB 的頭結點。

c語言實現:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct node{
int number;
struct node * next;
}Node,*LinkList;
//創建單鏈表,尾插法
LinkList initLink(){
LinkList head=(LinkList)malloc(sizeof(Node));//創建頭節點
LinkList temp=head;//聲明一個指針,用於遍歷
LinkList p;
printf("鏈表初始化,輸入0結束:\n");
int num;
while(1){
scanf("%d",&num);
fflush(stdin); //清空緩存
if (num==0) return head;//判斷是否停止
p =(LinkList)malloc(sizeof(Node));
p->number=num;
p->next=NULL;
temp->next=p;
temp=p;
}
}
//遍歷列表
void travelList(LinkList pNode){
LinkList temp=pNode;//用於遍歷
int num;
while(temp->next){
temp=temp->next;
num=temp->number;
printf("%d\n",num);
}
}
void Combine(LinkList La, LinkList Lb, LinkList Lc){
LinkList pa,pb,pc;
pa = La->next;
pb = Lb->next;
Lc = pc = La;
while(pa && pb){
if(pa->number <= pb->number){
pc->next = pa;
pc = pa;
pa = pa->next;
}
else{
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
pc->next = pa? pa:pb;
free(Lb);
travelList(Lc);
}
int main(){
Node *LA,*LB;//兩個鏈表
printf("初始化順序表a\n");
LA=initLink();
printf("初始化后的鏈順序表La\n");
travelList(LA);
printf("初始化順序表lb\n");
LB=initLink();
printf("初始化后的順序表Lb\n");
travelList(LB);
LinkList Lc;//第三個表Lc
printf("合並化后的鏈表為:\n");
Combine(LA,LB,Lc);
}
調試結果:

