2018.5.21(荷兰国旗问题--链表版)

用链表解决荷兰国旗问题可以保证排序的稳定性

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;

struct List
{
    int data;
    List *next;
};

void print(List *head)
{
    for(List *p=head;p!=NULL;p=p->next)
        printf("%d ",p->data);
    printf("\n");
}

List *Insert(List *head,int number)
{
    List *new_point;
    List *tail_point;
    List *current_point;

    new_point=(List *)malloc(sizeof(List));
    new_point->data=number;
    new_point->next=NULL;

    if(head==NULL)
        return new_point;

    tail_point=head;
    while(tail_point!=NULL)
    {
        current_point=tail_point;
        tail_point=tail_point->next;
    }
    tail_point=new_point;
    current_point->next=tail_point;

    return head;
}

List *Create(int n)
{
    List *head=NULL;
    printf("Input %d numbers:\n",n);
    for(int i=1;i<=n;i++)
    {
        int number;
        scanf("%d",&number);
        head=Insert(head,number);
    }

    return head;
}

List *Solve(List *small_s,List *small_e,List *equal_s,List *equal_e,List *big_s,List *big_e)//将将小于num,等于num,大于num的数合成一个链表
{
    if(small_s==NULL)
    {
        if(equal_s!=NULL)
        {
            equal_e->next=big_s;
            return equal_s;
        }
        return big_s;
    }
    if(equal_s==NULL)
    {
        small_e->next=big_s;
        return small_s;
    }

    small_e->next=equal_s;
    equal_e->next=big_s;
    return small_s;
}

List *Marge(List *head,int num)//将小于num,等于num,大于num的数分别归并;
{
    List *small_s=NULL,*small_e=NULL;
    List *equal_s=NULL,*equal_e=NULL;
    List *big_s=NULL,*big_e=NULL;
    List *new_point;

    for(List *p=head;p!=NULL;p=p->next)//如果将此循环中的new_point 改成p,会出错;
    {
        new_point=(List*)malloc(sizeof(List));
        new_point->data=p->data;
        new_point->next=NULL;

        small_s=(small_s==NULL&&new_point->data<num)?new_point:small_s;
        equal_s=(equal_s==NULL&&new_point->data==num)?new_point:equal_s;
        big_s=(big_s==NULL&&new_point->data>num)?new_point:big_s;
    }

    for(List *p=head;p!=NULL;p=p->next)//需从新开辟一块空间,不能直接用p;且不能直接将p的地址传递给new_point
    {
        new_point=(List*)malloc(sizeof(List));//new_point=p; new_point->next=NULL,直接将p的地址传递给new_point也是错的
        new_point->data=p->data;
        new_point->next=NULL;

        //printf("********%d\n",p->data);
        if(new_point->data<num)
        {
            if(small_e==NULL)
            {
                small_e=new_point;
                small_s->next=small_e;
            }
            else
            {
                small_e->next=new_point;
                small_e=new_point;
            }
            continue;
        }
        if(new_point->data==num)
        {
            if(equal_e==NULL)
            {
                equal_e=new_point;
                equal_s->next=equal_e;
            }
            else
            {
                equal_e->next=new_point;
                equal_e=new_point;
            }
            equal_e->next=NULL;
            continue;
        }
        if(new_point->data>num)
        {
            if(big_e==NULL)
            {
                big_e=new_point;
                big_s->next=big_e;
            }
            else
            {
                big_e->next=new_point;
                big_e=new_point;
            }
            big_e->next=NULL;
            continue;
        }
    }

    if(small_s!=NULL)
    {
        List *p=small_s;
        small_s=small_s->next;
        free(p);
    }
    if(equal_s!=NULL)
    {
        List *p=equal_s;
        equal_s=equal_s->next;
        free(p);
    }
    if(big_s!=NULL)
    {
        List *p=big_s;
        big_s=big_s->next;
        free(p);
    }

    head=Solve(small_s,small_e,equal_s,equal_e,big_s,big_e);//将将小于num,等于num,大于num的数合成一个链表

    return head;
}

int main()
{
    int n;
    int num;

    printf("Input multiple sets of numbers until a number less than or equal to zero!\n");
    while(cin>>n)
    {
        if(n==0)
            break;

        List *head;
        head=Create(n);//创建链表

        printf("Input a number\n");
        cin>>num;

        head=Marge(head,num);//将小于num,等于num,大于num的数分别归并;
        print(head);//打印结果;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值