刺破数据结构-数据结构学习总结(第二章)b站 有序表合并(顺序表加链表实现)

文章详细介绍了C语言中线性表的结构以及合并操作,包括顺序表的合并、有序表的合并(使用顺序表和链表实现),涉及了初始化、插入、删除和查找等基本操作。
摘要由CSDN通过智能技术生成

王卓老师的课:

第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的区别一起给出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值