顺序表和链表的归并,归并排序

1,顺序表的归并

#include <stdio.h>
#include <stdlib.h>
#define MAX(X,Y) (X>Y?X:Y)
#define MAXSIZE 10
typedef struct List//创建一个顺序表类型
{
    int arr[MAXSIZE];
    int size;
}List;
int check(int a, List*b)//检查顺序表里是否包含某个整型
{
    int i = 0;
    for(i = 0; i < b->size; i++)
    {
        if(a == b->arr[i])
            return 0;
    }
    return 1;
}
void Merge(List* a, List* b)//合并函数,传入两个顺序表类型地址
{
    int i = 0;
    while(i < a->size && b->size <= MAXSIZE)//遍历顺序表a,找到和b里元素不同的,则插入到b的最后面,当遍历完a或者b顺序表已经满了,就停止循环
    {
        if(check(a->arr[i], b))
        {
            b->arr[b->size++] = a->arr[i];
        }
        i++;
    }
}
int main()
{
    List a = {{1,2,3,8,9},5};//顺序表变量
    List b = {{3,4,5,6},4};
    Merge(&a,&b);//因为要改变b的值,所以传址,a可以传址,也可以传值,看个人喜好
    int i = 0;
    for(i = 0; i < b.size; i++)
    {
        printf("%d ",b.arr[i]);
    }

    return 0;

}

结果是:

2,单链表归并

#include <stdio.h>
#include <stdlib.h>
#define MAX(X,Y) (X>Y?X:Y)
#define MAXSIZE 10
typedef struct Elem//创建一个链表类型
{
    int data;
    struct Elem* p;
}elem;
void creat_link(elem* a, int b)//创建一个单链表,并且赋值
{
    int i = 0;
    int input = 0;
    elem* tmp = a;
    for(i = 0; i < b; i++)
    {
        elem*num = malloc(sizeof(elem));
        num->p = NULL;
        tmp->p = num;
        tmp = num;
        printf("请输入元素的值:>");
        scanf("%d",&input);
        num->data = input;
    }

}
void Merge(elem* a, elem*b)//尾部插入法
{
    elem* start = a;//临时变量保存链表a的起点地址,每次循环结束要重置到起点
    while(b->p)
    {
        while(a->p)//循环拿b的值和a的每一个元素比较
        {
            if(b->p->data == a->p->data)
            {
                b = b->p;//如果相等,不做任何操作,跳出内循环,拿b的下一个元素再来比较
                break;
            }
            else
            {
                a = a->p;//如果值不相等,再取下一个值比较
            }
        }
        if(!a->p)//能循环到这里,a->p为空的话,说明值不相等,需要把b->p这个地址放到链表a的尾部
        {
            a->p = b->p;//把b->p这个地址放到链表a的尾部
            b->p = b->p->p;//然后把b的头结点的地址域值改成下一个元素的地址
            a->p->p = NULL;//把a最后一个元素的地址域值设为空
        }
        a = start;//重置a的起点指向头结点
    }
}
int main()
{
    elem* head_a = (elem*)malloc(sizeof(elem));//创建头结点空间和地址
    elem* start_a = head_a;//创建链表入口
    creat_link(start_a, 3);//这里要定义几个元素,这里可以随意修改

    elem* head_b = (elem*)malloc(sizeof(elem));//创建第二个头结点空间和地址
    elem* start_b = head_b;//创建链表入口
    creat_link(start_b, 5);//这里要定义几个元素,这里可以随意修改

    Merge(start_a, start_b);//合并两个链表
    while(head_a->p)
    {
        printf("%d",head_a->p->data);
        head_a = head_a->p;
    }

    return 0;
}

输入:5 6 7, 1 2 3 4 5,结果为:

结论是顺序表和单链表,在时间和空间度上区别不大,但是代码的复杂和理解上,顺序表要简单明了得多

3,顺序表归并排序(不检查相同的数字,给的顺序表也应该是有序的)

#include <stdio.h>
#include <stdlib.h>
#define MAX(X,Y) (X>Y?X:Y)
#define MAXSIZE 10
typedef struct L
{
    int arr[20];
    int size;
}L;
void Merge(L* a, L* b)
{
    L c = {{0}, 0};//定义一个顺序表,用来存放排完序后的元素
    int i = 0;
    int j = 0;
    while(i < a->size&& j < b->size)//循环从a和b里面拿元素对比
    {
        if(a->arr[i] < b->arr[j])//如果a的数较小,把这个较小的数放进c
        {
            c.arr[c.size] = a->arr[i];
            i++;//再拿下一个数来比较
            c.size++;//c里面放了一个值后,size加上1
        }
        else
        {
            c.arr[c.size] = b->arr[j];//如果b的数较小,把这个较小的数放进c
            j++;
            c.size++;
        }
    }
    while(i < a->size)//当上面整个循环结束后,如果这个条件成立,说明b循环结束了,a里面还有值没有取出
    {
        c.arr[c.size] = a->arr[i];//把剩下的值全部放进c
        i++;
        c.size++;
    }
    while(j < b->size)//当上面整个循环结束后,如果这个条件成立,说明a循环结束了,b里面还有值没有取出
    {
        c.arr[c.size] = b->arr[j];//把剩下的值全部放进c
        j++;
        c.size++;
    }
    int k = 0;
    for(k = 0;k < c.size; k++)//打印c里面arr的值
    {
        printf("%d ",c.arr[k]);
    }


}
int main()
{
    L a = {{4,5,8,11,20}, 5};
    L b = {{2,6,8,13,19}, 5};
    Merge(&a, &b);
    return 0;
}

这里需要创建一个新的顺序表来储存数据

4,有序表链表归并排序

#include <stdio.h>
#include <stdlib.h>
#define MAX(X,Y) (X>Y?X:Y)
#define MAXSIZE 10
typedef struct Elem//创建一个链表类型
{
    int data;
    struct Elem* p;
}elem;
void creat_link(elem* a, int b)//创建一个单链表,并且赋值
{
    int i = 0;
    int input = 0;
    elem* tmp = a;
    for(i = 0; i < b; i++)
    {
        elem*num = malloc(sizeof(elem));
        num->p = NULL;
        tmp->p = num;
        tmp = num;
        printf("请输入元素的值:>");
        scanf("%d",&input);
        num->data = input;
    }
}

void Merge(elem* a, elem* b, elem* c)
{
    elem* pa = a->p;//创建三个指针,分别对应a,b的第一个元素,pc指向头结点
    elem* pb = b->p;
    elem* pc = c;
    while(pa && pb)
    {
        if(pa->data < pb->data)
        {
            pc->p = pa;
            pc = pa;
            pa = pa->p;

        }
        else
        {
            pc->p = pb;
            pc = pb;
            pb = pb->p;
        }
    }
    pc->p = pa?pa:pb;
}

int main()
{
    elem* head_a = (elem*)malloc(sizeof(elem));//创建头结点空间和地址
    elem* start_a = head_a;//创建链表入口
    creat_link(start_a, 3);//这里要定义几个元素,这里可以随意修改

    elem* head_b = (elem*)malloc(sizeof(elem));//创建第二个头结点空间和地址
    elem* start_b = head_b;//创建链表入口
    printf("第二个链表的值:\n");
    creat_link(start_b, 5);//这里要定义几个元素,这里可以随意修改

    elem* c = start_a;//定义一个新的链表,入口位置和a相同,用来存储排好序的元素

    Merge(start_a, start_b, c);//合并两个链表
    while(c->p)
    {
        printf("%d ",c->p->data);
        c = c->p;
    }
    return 0;
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值