前言
大家好,我是极速脆皮猫。鉴于严蔚敏的数据结构(C语言版)中大部分代码存在伪代码的情况,笔者将对其进行补全和完善,以便于学习或研究数据结构的你们能更加准确地掌握其中的奥妙。
第二章 线性表
2.1 线性表的类型定义
算法2.1
问题描述:已知线性表LA和LB中的数据元素按值非递减有序排列,现要求将LA和LB归并为一个新的线性表LC,且LC中的数据元素仍按值非递减有序排列。例如设
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LA=(3,5,8,11)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LB=(2,6,8,9,11,15,20)
则 ~~~~~~~~~~~~~~~~~~~~~~ LC=(2,3,5,6,8,8,9,11,11,15,20)
题解(Solution):
#include<stdio.h>
#include<stdlib.h>//内存分配函数所需库
#define MAXSIZE 20 //线性表存储空间的初始分配量
#define OK 1 //成功标识
#define ERROR 0 //失败标识
typedef int Status;//函数返回值类型
typedef int ElemType;//顺序表元素类型
这是对代码主要部分的准备。
//顺序表的结构
typedef struct{
ElemType *elem;//数据
int len;//顺序表长度
}List;
这是顺序表的基本结构。
//构造一个空的线性表L
Status InitList(List* L){
L -> elem = (ElemType *)malloc(MAXSIZE*sizeof(ElemType));
if(!L -> elem){
return ERROR;
}
L -> len = 0;
return OK;
}
构造函数。
/*
插入操作
初始条件:顺序表L已存在
操作结果:在L中的第i个位置之前插入新的数据元素e,L的长度加1
*/
Status ListInsert(List *L, int i, ElemType e){
int k;
if (L->len == MAXSIZE){
//线性表已满
return ERROR;
}
if (i < 1 || i > L->len+1){
//当i不在范围内时
return ERROR;
}
if (i <= L->len){
//若插入位置不在表尾
for(k = L->len-1;k >= i-1;k--){
L->elem[k+1] = L->elem[k];
}
}
L->elem[i-1] = e; //将新元素插入
L->len++; //长度加1
return OK;
}
插入函数
/*
获取元素操作
初始条件:顺序表L已存在
操作结果:用e返回L中第i个数据元素的值
*/
Status GetElem(List L, int i, ElemType *e){
if(L.len == 0 || i<1 || i>L.len){
return ERROR;
}
*e = L.elem[i-1];
return OK;
}
获取指定位置的函数。
Status ListLength(List L){
return L.len;
}
获取顺序表的长度
/*打印线性表中的所有元素*/
void OutPut(List L){
printf("当前顺序表的长度:%d\n", L.len);
for(int i = 0; i < L.len; i++){
printf("%d ",L.elem[i]);
}
printf("\n");
}
打印顺序表的长度和所有元素
核心代码:
void MergeList(List La,List Lb,List &Lc){
//已知线性表La和Lb中的数据元素按非递减排列。
//归并La和Lb得到新的线性表Lc,Lc的数据元素也按非递减排列。
int i,j,k,ai,bj;
i=j=1;k=0;
La.len=ListLength(La);Lb.len=ListLength(Lb);
while((i<=La.len)&&(j<=Lb.len)){
GetElem(La,i,&ai);GetElem(Lb,j,&bj);
if(ai<=bj) ListInsert(&Lc,++k,++i);
else{
ListInsert(&Lc,++k,bj);
++j;
}
}
while(i<=La.len){
GetElem(La,i++,&ai);
ListInsert(&Lc,++k,ai);
}
while(i<=Lb.len){
GetElem(Lb,i++,&bj);
ListInsert(&Lc,++k,bj);
}
}
这就是这个算法的核心代码。
完整代码:
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 20 //线性表存储空间的初始分配量
#define OK 1 //成功标识
#define ERROR 0 //失败标识
typedef int Status;
typedef int ElemType;
//顺序表的结构
typedef struct{
ElemType *elem;
int len;
}List;
//构造一个空的线性表L
Status InitList(List* L){
L -> elem = (ElemType *)malloc(MAXSIZE*sizeof(ElemType));
if(!L -> elem){
return ERROR;
}
L -> len = 0;
return OK;
}
/*
插入操作
初始条件:顺序表L已存在
操作结果:在L中的第i个位置之前插入新的数据元素e,L的长度加1
*/
Status ListInsert(List *L, int i, ElemType e){
int k;
if (L->len == MAXSIZE){
//线性表已满
return ERROR;
}
if (i < 1 || i > L->len+1){
//当i不在范围内时
return ERROR;
}
if (i <= L->len){
//若插入位置不在表尾
for(k = L->len-1;k >= i-1;k--){
L->elem[k+1] = L->elem[k];
}
}
L->elem[i-1] = e; //将新元素插入
L->len++; //长度加1
return OK;
}
/*打印线性表中的所有元素*/
void OutPut(List L){
printf("当前顺序表的长度:%d\n", L.len);
for(int i = 0; i < L.len; i++){
printf("%d ",L.elem[i]);
}
printf("\n");
}
/*
获取元素操作
初始条件:顺序表L已存在
操作结果:用e返回L中第i个数据元素的值
*/
Status GetElem(List L, int i, ElemType *e){
if(L.len == 0 || i<1 || i>L.len){
return ERROR;
}
*e = L.elem[i-1];
return OK;
}
Status ListLength(List L){
return L.len;
}
void MergeList(List La,List Lb,List &Lc){
//已知线性表La和Lb中的数据元素按非递减排列。
//归并La和Lb得到新的线性表Lc,Lc的数据元素也按非递减排列。
int i,j,k,ai,bj;
i=j=1;k=0;
La.len=ListLength(La);Lb.len=ListLength(Lb);
while((i<=La.len)&&(j<=Lb.len)){
GetElem(La,i,&ai);GetElem(Lb,j,&bj);
if(ai<=bj) ListInsert(&Lc,++k,++i);
else{
ListInsert(&Lc,++k,bj);
++j;
}
}
while(i<=La.len){
GetElem(La,i++,&ai);
ListInsert(&Lc,++k,ai);
}
while(i<=Lb.len){
GetElem(Lb,i++,&bj);
ListInsert(&Lc,++k,bj);
}
}
int main(){
List La,Lb,Lc;
InitList(&La);
InitList(&Lb);
InitList(&Lc);
ListInsert(&La,1,3);
ListInsert(&La,2,5);
ListInsert(&La,3,8);
ListInsert(&La,4,11);
ListInsert(&Lb,1,2);
ListInsert(&Lb,2,6);
ListInsert(&Lb,3,8);
ListInsert(&Lb,4,9);
ListInsert(&Lb,5,11);
ListInsert(&Lb,6,15);
ListInsert(&Lb,7,20);
MergeList(La,Lb,Lc);
OutPut(La);
OutPut(Lb);
OutPut(Lc);
}
运行结果: