今天实现数据结构课本上一个很简单的算法~
功能:实现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程序写完啦~运行还是很成功的!
运行结果:
奥里给!