王卓老师的课:
第04周08--2.7线性表的应用1--线性表的合并_哔哩哔哩_bilibili
第04周09--2.7线性表的应用2--有序表的合并--用顺序表实现_哔哩哔哩_bilibili
线性表的两个操作的全部代码:
//调入头文件
#include <stdio.h>
#include <stdlib.h>
#define MAXLENGTH 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int ElemType;
typedef struct
{
ElemType *data;
int length;
//此处不做动态分配。每个线性表长度是固定的。
}SqList;
Status InitList(SqList *L){
L->data = (ElemType*)malloc(MAXLENGTH*sizeof(ElemType));
if(!L->data) exit(OVERFLOW);
L->length = 0;
return OK;
}
Status WriteList(SqList *L){
printf("输入顺序表表长:");
scanf("%d",&L->length);
printf("输入%d个元素",L->length);
for(int i=0;i<L->length;i++)
{
scanf("%d",&L->data[i]);
}
}
Status PrintList(SqList *L)
{
if (!L->data){
return ERROR;
}
printf("顺序表元素为:");
for(int i = 0; i < L->length;i++)
{
printf("%d ",L->data[i]);
}
printf("\n");
}
Status DestroyList(SqList *L)
{
L->length = 0;
free(L->data);
printf("已经销毁");
return OK;
}
Status ClearList(SqList *L)
{
L->length = 0;
printf("已经清除");
return OK;
}
Status GetLength(SqList L){
return L.length;
}
Status Isempty(SqList L){
if(L.length == 0) return 1;
else return 0;
}
ElemType GetElem(SqList L,int i,ElemType *e)
{
if(i<1||i>L.length) return OVERFLOW;
*e =L.data[i-1];
return OK;
}
int LocateElem(SqList L,ElemType e){
for(int i=0;i<L.length;i++){
if(L.data[i] == e) return i+1;
}
return 0;
}
Status ListInsert(SqList *L,int i,ElemType e)
{
if(i<1||i>L->length+1) return ERROR;
if(L->length ==MAXLENGTH) return ERROR;
for(int j=L->length-1;j>=i-1;j--){
L->data[j+1]=L->data[j];
}
L->data[i-1]=e;
L->length++;
return OK;
}
Status ListDelete(SqList *L,int i){
if(i<1||(i>=L->length)) return ERROR;
for (int j=i;j<=L->length-1;j++)
{
L->data[j-1]=L->data[j];
}
L->length--;
}
//线性表合并
void unin(SqList *L1,SqList L2)
{
int L1_len,L2_len;
ElemType e;
L1_len = GetLength(*L1);
L2_len = GetLength(L2);
for(int i =1;i<=L2_len;i++)
{
GetElem(L2,i,&e);
if(!LocateElem(*L1,e)) ListInsert(L1,++L1_len,e);
}
}
//有序表合并
void MergeList_Sq(SqList LA,SqList LB,SqList *LC)
{
ElemType *pa = LA.data;
ElemType *pb = LB.data;
LC->length = LA.length+LB.length;
LC->data = (ElemType*)malloc(sizeof(ElemType)*LC->length);
ElemType *pc = LC->data;
ElemType *pa_last =LA.data + LA.length -1;
ElemType *pb_last =LB.data + LB.length -1;
while(pa<=pa_last && pb<=pb_last)
{
if(*pa<=*pb) *pc++ = *pa++;
else *pc++ = *pb++;
}
while (pa<=pa_last) *pc++ = *pa++;
while (pb<=pb_last) *pc++ = *pb++;
}
int main(){
SqList L,L2,L3;
ElemType e;
int i;
InitList(&L);
WriteList(&L);
PrintList(&L);
printf("长度:%d",GetLength(L));
printf("空:%d\n",Isempty(L));
InitList(&L2);
WriteList(&L2);
PrintList(&L2);
printf("长度:%d",GetLength(L2));
printf("空:%d\n",Isempty(L2));
unin(&L,L2);
PrintList(&L);
printf("长度:%d",GetLength(L));
printf("空:%d\n",Isempty(L));
MergeList_Sq(L,L2,&L3);
PrintList(&L3);
printf("长度:%d",GetLength(L3));
printf("空:%d\n",Isempty(L3));
/*
printf("需要增加的位置:");
scanf("%d",&i);
printf("需要增加的元素:");
scanf("%d",&e);
ListInsert(&L,i,e);
printf("长度:%d",GetLength(L));
PrintList(&L);
printf("需要减少的元素序号:");
scanf("%d",&e);
ListDelete(&L,e);
PrintList(&L);
printf("长度:%d",GetLength(L));
getchar();
printf("请输入需要查询的元素序号");
scanf("%d",&i);
GetElem(L,i,&e);
printf("所对应的元素为:%d",e);
printf("请输入需要查询的元素");
scanf("%d",&e);
printf("所对应的元素序号为:%d\n",LocateElem(L,e));
*/
ClearList(&L);
DestroyList(&L);
printf("空:%d",Isempty(L));
return 0;
}
线性表的合并部分代码:
//线性表合并
void unin(SqList *L1,SqList L2)
{
int L1_len,L2_len;
ElemType e;
L1_len = GetLength(*L1);
L2_len = GetLength(L2);
for(int i =1;i<=L2_len;i++)
{
GetElem(L2,i,&e);
if(!LocateElem(*L1,e)) ListInsert(L1,++L1_len,e);
}
}
合并的基本思想:以一个表为载体(L1)将另外一个表(L2)融合进去。那怎么融合呢?先取出L2中的一个元素,如果L1中有该元素即不用插入,否则将该元素插入到线性表的尾部。元素插入L1表长记得+1。
线性表的合并主要用到了3个基本操作,获取线性表长度,匹配线性表的元素,线性表的插入。
第04周10--2.7线性表的应用3--有序表的合并--用链表实现_哔哩哔哩_bilibili
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef int Status;
/*
typedef struct{
char num[8];
char name[8];
int score;
}ElemType;
*/
typedef struct Lnode{
ElemType data;
struct Londe *next;
}Lnode,*Linklist;
//自己定义自己,嵌套定义。
void printLnode(Linklist L){
Lnode *p = L->next;
if(!p) return printf("kong");
while(p){
printf("%d ",p->data);
p = p->next;
}
}
Status InitList_L(Linklist *L)
{
*L = (Linklist)malloc(sizeof(Lnode));
(*L)->next =NULL;
return OK;
}
Status void_L(Linklist L)
{
if (L->next)
{
return ERROR;
}
else return OK;
}
Status Destroy_L(Linklist *L)
{
Lnode *p;
while ((*L))
{
p = *L;
(*L) = (*L)->next;
free(p);
}
}
//销毁整个链表的时候,需要将整个链表包括头结点全部删除,清空时需要进行保留。
Status Clear_L(Linklist *L)
{
Lnode* p,*q;
p =(*L)->next;
q = p->next;
while (q)
{
free(p);
p = q;
q = q->next;
}
free(p);
(*L)->next = NULL;
return OK;
}
int ListLength(Linklist L)
{
Lnode *p;
p = L->next;
int i = 0;
while (p)
{
i++;
p = p->next;
}
return i;
}
Status GetElem_L(Linklist L,int i,ElemType *e)
{
Lnode *p;int j=1;
p = L->next;
while(p && j<i){
p = p->next;
j++;
}
if(!p||j>i) return ERROR;
*e = p->data;
return OK;
}
Lnode * LocateElem_L(Linklist L,ElemType e)
{
Lnode* p = L->next;
while(p && p->data!=e)
{
p = p->next;
}
return p;
}
int LocateElem_L2(Linklist L,ElemType e)
{
Lnode* p = L->next;int j=1;
while(p && p->data!=e){
p = p->data;
j++;
}
if(p) return j;
else return ERROR;
}
Status ListInsert_L(Linklist*L,int i,ElemType e)
{
Lnode * p;
p = (*L);
int j = 0;
while (p && j<i-1){
p = p->next;j++;
}
if(!p||j>i-1) return ERROR;
Lnode* s = (Lnode*)malloc(sizeof(Lnode));
s->data = e;
s->next = p->next;
p->next = s;
}
Status ListDelete(Linklist *L,int i,ElemType *e)
{
Lnode *p = L;
Lnode *q = L;
int j =0;
while (p->next && j<i-1)
{
p = p->next;
j++;
}
if(!p->next||j>i-1) return ERROR;
q = p->next;
p->next = q->next;
e = q->data;
free(q);
return OK;
}
//头插法:
void CreateList_H(Linklist *L,int n)
{
*L = (Lnode*)malloc(sizeof(Lnode));
(*L)->next = NULL;
for(int i=n;i>0;i--)
{
Lnode *p = (Lnode*)malloc(sizeof(Lnode));
printf("请输入第%d个元素",n-i+1);
scanf("%d",&(p->data));
p->next = (*L)->next;
(*L)->next = p;
}
}
//尾插法:
void CreateList_R(Linklist *L,int n)
{
(*L) = (Lnode*)malloc(sizeof(Lnode));
(*L)->next = NULL;
//初始化
Lnode *r = *L;
for(int i = 0; i < n; ++i)
{
Lnode *p = (Lnode*)malloc(sizeof(Lnode));
p->next = NULL;
r->next = p;
r = p;
printf("请输入第%d个元素",i+1);
scanf("%d",&(p->data));
}
}
void MergeList_L(Linklist *L1,Linklist* L2,Linklist* L3)
{
Lnode *pa = (*L1)->next;
Lnode *pb = (*L2)->next;
Lnode *pc = *L1;
*L3 = *L1;
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(*L2);
}
int main()
{
Linklist L,L2,L3;
int i;
ElemType e=0;
//头插法初始化链表
printf("请输入需要初始化的元素数量:");
scanf("%d",&i);
CreateList_R(&L,i);
printLnode(L);
printf("请输入需要初始化的元素数量:");
scanf("%d",&i);
CreateList_R(&L2,i);
printLnode(L2);
MergeList_L(&L,&L2,&L3);
printLnode(L3);
/*
//输入长度
printf("%d",ListLength(L));
//查找需要的长度
printf("请输入需要查找的元素:");
scanf("%d",&i);
GetElem_L(L,i,&e);
printf("\ne=%d",e);
//删除所需要的元素
printf("请输入需要删除的元素位置:");
scanf("%d",&i);
ListDelete(L,i,&e);
printf("\ne=%d",e);
printLnode(L);
//清除链表
Clear_L(&L);
//实现尾插操作
printf("请输入需要初始化的元素数量:");
scanf("%d",&i);
CreateList_R(&L,i);
printf("\n");
printLnode(L);
//删除所需要的元素
printf("请输入需要插入的元素位置:");
scanf("%d",&i);
printf("请输入需要插入的元素:");
scanf("%d",&e);
ListInsert_L(&L,i,e);
printLnode(L);
*/
return 0;
}
还有部分解析将在下一篇中同*str++与*++str的区别一起给出。