线性表-顺序存储结构-实现取交集A=A∪B

今天实现数据结构课本上一个很简单的算法~

功能:实现A=A∪B运算。

           由用户输入A,B两个集合内容,算法求出两个集合并集并输出。

算法结构:线性表的顺序存储结构。(数组)


线性表的顺序存储结构

结构体

typedef struct{
    char * array;//存储空间基地址
    int length;//当前长度(数组中已存取的数据个数)
    int listsize;//当前分配的存储容量(数组能存储的数据总个数)
}SqList;

便于内存分配的宏定义:

# define LIST_INIT_SIZE 5//线性表存储空间的初始分配量
# define LISTINCREAMENT 1//线性表存储空间的分配增量

本程序用到的所有函数声明:

int InitList_Sq(SqList *a);//初始化顺序存储线性表
int ListEnlarge_Sq(SqList *a);//增大顺序存储线性表存储空间
int ListInsert_Sq(SqList * a,int i,int e);//插入元素
int LocateElem_Sq(SqList L,int e,int (*compare)(int,int));//定位满足要求的线性表中元素
void union_ab(SqList * a,SqList * b);//求并集函数
void display_array(SqList a);//显示线性表内容
void Input_array(SqList * a);//用户输入线性表内容数据
int GetElem(SqList a,int i,int *e);//找到所需次序的元素
int equal(int a,int b);//数值比较函数

下面具体说明每个函数的编写!

1.  int InitList_Sq(SqList *a)

作用:初始化数组。

int InitList_Sq(SqList *a)
{  

a->array=(char *)malloc((LIST_INIT_SIZE)*sizeof(char));//分配基地址
if(!a->array) exit(1);//未分配空间成功
a->length=0;//当前储存元素的长度
a->listsize=LIST_INIT_SIZE;//总空间
return 0;

}

2. void Input_array(SqList * a)

作用:由用户输入线性表内容。

       (这里规定输入不同元素之间要敲个空格,输入完了要打个回车!)

void Input_array(SqList * a)
{
    printf("Please input array.\n");
    int i;//计数输入元素个数
    char ch,sh;
    for(i=0; ;i++)
    {

        ch=getchar();//用户输入字符
        a->array[i]=ch;
        a->length++;

        sh=getchar();//用户在输入不同元素间敲入空格
        if(sh==10)//判断输入的元素是不是回车
        {
            break;
        }
       
        if(a->length==a->listsize)//增大数组内存
        {
            ListEnlarge_Sq(a);
        }

    }
    printf("You have finished the input.\n");

}

画个重点呀~

请关注1.getchar()函数的用法,空格等非用户想输入的数据也会被读取,注意处理!

            2.判断是否输入回车的方法。(关于字符和ASCII表..)

3.int ListEnlarge_Sq(SqList *a)

int ListEnlarge_Sq(SqList *a)
{
    char * newbase;//分配一个新基地址
    newbase=(char*)realloc(a->array,sizeof(char)*(a->listsize+LISTINCREAMENT));//重新分配
    if(!newbase) return(1);//分配失败
    a->array=newbase;//基地址移过去
    a->listsize=a->listsize+LISTINCREAMENT;//总内存增大
}

关注:整个函数的用法!!!尤其是realloc用法!

4.void display_array(SqList a)

作用:打印出线性表内容。

void display_array(SqList a)
{
    int i;
    for(i=0;i<a.length;i++)
    {
        printf("%c ",a.array[i]);
    }
}

 

5.int GetElem(SqList a,int i,int *e)

作用:取得线性表a中第I个元素,并赋值给e。

int GetElem(SqList a,int i,int *e)
{
   if(i>a.length||i<=0)
   {
       printf("Can't get element.");
       return 1;
   }//不合法I值
   char ch;
   ch=a.array[i-1];
   *e=atoi(&ch);
    return 0;
}

 关注:atoi()函数的用法。

将字符串char*转换为对应的int整数值。

如5(char)→5(int),而非ascii表中对应的整数值(显然并不是你想表达的)。

这里的另一个实现方法:若是char ch = '6';你想让int a = ch 也为6,可以采用减法:

如 a=ch-'0';

注意该函数是对于字符串char[](即一堆字符)的操作,所以这里先用ch取得了a.array[]字符串中的所需的一个字符。

6.int equal(int a,int b)

简简单单就是真的数值比较函数,根据需要可以改成其他的大于小于什么的。

函数用来判断某元素满足的条件。

int equal(int a,int b)
{
    if(a==b)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

7.int ListInsert_Sq(SqList * a,int i,int e)
作用:在顺序线性表a中第i个位置之前插入新的元素e

int ListInsert_Sq(SqList * a,int i,int e){
//在顺序线性表a中第i个位置之前插入新的元素e
if(i<1||i>a->length+1){
    return 1;
}//i值不合法
char * newbase;
if(a->length>=a->listsize)//当前存储空间已满,再分配增量
{
    newbase=(char *)realloc(a->array,(a->listsize+LISTINCREAMENT)*sizeof(char));
    if(!newbase) exit(1);
    a->array=newbase;
    a->listsize+=LISTINCREAMENT;

}
char *q, *p;
q=&(a->array[i-1]);//注意第几个元素与下标的关系
 //移动数组元素:从后往前移动
for(p=&(a->array[a->length-1]);p>=q;--p){ //数组中地址连续,也可以比大小

*(p+1)=*(p);//插入位置与其之后的元素后移
}
q=itoa(e,q,10);
a->length++;
return 0;

}

关注:1.数组中元素的移动方法。

2.char*=itoa(int,char*,int)函数用法,将int型整数转换为对应的char型字符。

最后那个int是10进制/2进制/...

3.补充:c语言中所有的子函数是平行关系,意味着它们可以互相引用,但不可互相嵌套定义。

 

 8.int LocateElem_Sq(SqList L,int e,int (*compare)(int,int))

作用:在顺序表中查找第一个值与e 满足条件compare()的元素的位序(1,2......)
若找到,返回位序,否则返回0.

int LocateElem_Sq(SqList L,int e,int (*compare)(int,int)){

int i=1;
char  p;
int a;

p=L.array[0];
a=atoi(&p);

for(;i<=L.length&&!(*compare)(a,e);i++)
{
   p=L.array[i];
    a=atoi(&p);
}
if(i<=L.length) return i;
else return 0;

}

关注:atoi用法(包括对字符or字符串的处理) 、int ,char转换。

          函数指针的使用!

9.void union_ab(SqList * a,SqList * b)

作用:求并集。

 

void union_ab(SqList * a,SqList * b){
    int a_len,b_len;
    a_len=a->length;
    b_len=b->length;

    int i;
    int e;

    for(i=1;i<=b_len;i++){
        GetElem(*b,i,&e);
        if(!LocateElem_Sq(*a,e,equal))
        {
        ListInsert_Sq(a,a->length+1,e);//插入时就改变了a.length
        }
    }
}

关注:++和+1的区别。

如在If语句中,a+1仅表示if中使用的为该表达式的值,a原值不改变。但a++语句会改变a的值。

 

10.主函数main

int main()
{

c=getchar();

SqList a,b;
InitList_Sq(&a);
InitList_Sq(&b);

Input_array(&a);
Input_array(&b);


printf("\nLet's display.\n");

display_array(a);
printf("alength %d",a.length);

printf("\n");

display_array(b);
printf("blength %d",b.length);

union_ab(& a,& b);

printf("\nLet's display the union.\n");

display_array(a);
printf("\ntotal length %d",a.length);

return 0;
}

okkkkkkkk程序写完啦~运行还是很成功的!

运行结果:

奥里给!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值