区间计算

题目.        使用gcc编译,所提供的必须是可输出正确结果的程序

 

1.允许两个操作,add(min,max)del(min,max),一开始区间内为空,每个操作后算出区间内的集合,要求能自动合并、拆分集合。例如:
操作1add(1,7)   区间内的集合:(1,7)
操作2add(9,10)  区间内的集合:(1,7)(9,10)
操作3del(3,5)   区间内的集合:(1,2)(6,7)(9,10)
操作4add(3,8)   区间内的集合:(1,10)  

整个区间的范围可能会在(0,2^32-1)之间。

要求给出add()del()的算法描述和代码实现,程序要实现输入输出即可供用户操作

 

以下是我自己写的代码:

main.c

/*
 * Copyright(C) 2010 XXXXX. All rights reserved.
 */
/*
 * main.c
 * Original Author: syijin@163.com 2010-08-19
 */
 
#include <stdio.h>
#include <string.h>
#include "List.h"
#include "qujian.h"

struct list_head *head;

int main(void)
{
    uint min, max;
    char text[10], str[5];   
   
    LIST_HEAD(qujian_head);
    qujian_t qjt_head;   

    head = &qujian_head;
    qjt_head.node = qujian_head;

    printf("Exit with 'end'!/n");

    while (1) {
        printf("Please input 'a min max' or 'd min max':");
        gets(text);
        sscanf(text, "%2s%u%u", str, &min, &max);

        if (str[0] == 'e') {
            break;
        }
        if (min > max) {
            printf("Input error!/n");
            continue ;
        }  
        if (str[0] == 'a') {
            add(min, max);
        } else if (str[0] == 'd') {
            del(min, max);
        }
        ceshi_travle(head);
    }
 
    travle(head);
   
    return 0;
}

 

qujian.h

#ifndef _QUJIAN_H_
#define _QUJIAN_H_

#include "list.h"

extern struct list_head *head;

typedef unsigned int uint;

typedef struct {
    uint min;
    uint max;
    struct list_head node;
} qujian_t;

struct list_head *new_qj(uint min, uint max, struct list_head *pos);
void add(uint min, uint max);
void hebing(struct list_head *start);
void travle(struct list_head *head);

void del(uint min, uint max);

void ceshi_travle(struct list_head * head);

#endif

 

qujian.c

#include <malloc.h>
#include <stdio.h>
#include "list.h"
#include "qujian.h"

/* 申请一个qujian_t空间,并插到pos后面,返回新节点的指针 */
struct list_head *new_qj(uint min, uint max, struct list_head *pos)
{
    qujian_t *p_qj;
   
    p_qj = (qujian_t *)malloc(sizeof(qujian_t));
    if (p_qj == NULL) {
        perror("malloc qujian_t error");
        return NULL;
    }
   
    p_qj->min = min;
    p_qj->max = max;
   
    list_add(&p_qj->node, pos);
    return &p_qj->node;
}

/* 添加一个新的区域 */
void add(uint min, uint max)
{
    struct list_head *new;
    qujian_t *pos;
   
    list_for_each_entry(pos, head, node, qujian_t) {
        if (min < pos->min) {
            new = new_qj(min, max, (&pos->node)->prev);
            hebing(new);
            return ;
        } else if (min <= pos->max +1) {          /* (1,7) (8,9); 因此要+1 */
            pos->max = (pos->max >= max)? pos->max : max;
            hebing(&pos->node);
            return ;           
        }     
    }

    new_qj(min, max, head->prev);                 /* 插到最后 */
   
    return ;
}

/* 判断start后面的区域是否与start重合,重合则合并 */
void hebing(struct list_head *start)

    uint max;
    struct list_head *n, *new;
    qujian_t *pos, *temp;

    temp = list_entry(start, qujian_t, node);
    max = temp->max;
    new = start;   
    /* 此处不能用list_head中的循环, 因为不是从head开始遍历的 */
    for (pos = list_entry((start)->next, qujian_t, node), n = pos->node.next;
             &pos->node != (head);
             pos = list_entry(n, qujian_t, node), n = pos->node.next) {
        if (max < pos->min - 1) {   /* 如(3,5) (1,2); 相等和差1归到下一种情况 */ 
            break;
        } else if (max <= pos->max) {
            (list_entry(new, qujian_t, node))->max = pos->max;
            list_del(n->prev);
            free(pos);       
            break;    
        } else {  
            list_del(&pos->node);
            free(pos);
        }
    }
  
   return ;  
}

 

 

/* 删除区间(min, max) */
void del(uint min, uint max)
{
    struct list_head *n;
    qujian_t *pos;
   
    add(min, max); /* 把要删除的区间先加入,这样min, max只会在同一个区间中 */

    list_for_each_entry_safe(pos, n, head, node, qujian_t) {
        if (min == pos->min && max == pos->max) {
            list_del(&(pos->node));
            free(pos);
            return ;
        } else if (min == pos->min) {
            pos->min = max + 1;
            return ;
        } else if (max == pos->max) {
            pos->max = min -1;
            return ;
        } else if (min > pos->min && max < pos->max) {
            new_qj(max + 1, pos->max, &pos->node);  /* 注意顺序,应在pos->max = min -1;之前 */
            pos->max = min -1;
            return ;
        }       
    }
    return ;
}

/* 遍历并释放空间 */
void travle(struct list_head *head)
{
    qujian_t *pos;
    struct list_head *n;
   
    list_for_each_entry_safe(pos, n, head, node, qujian_t) {
        printf("(%u,%u)", pos->min, pos->max);
        list_del(&(pos->node));
        free(pos);
    }
    return ;
}

 

ceshi.c

#include <stdio.h>
#include "qujian.h"

/* just travle */
void ceshi_travle(struct list_head *head)
{
    qujian_t *pos;
    struct list_head *n;
   
    list_for_each_entry_safe(pos, n, head, node, qujian_t) {
        printf("(%u,%u)", pos->min, pos->max);
    }
    printf("/n");
    return ;
}

lish.h在我的文章“双向链表操作“

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值