进行到现在,我们已经创建了Class Element类并且知道了一些自己定的默认的规则。
现在我们设计另外一个稍微比Class Element类复杂一点的类线性表类Class List。同样的,先把线性表所应该有的方法抽象出来:List.h
//List.h
Class List{
Class Element *head; //头节点(链式表专用)
Class Element *end; //尾节点(链式表专用)
int init_size; //初始大小,一开始表所能容纳的元素个数(数组表专用)
int length; //当前元素个数
int size; //当前表所能容纳的元素个数(数组表专用)
int increment; //如果超过了size所限定的个数,则表自动增加increment个元素的空间(数组表专用)
Class Element **elements; //线性表存储内容的首地址
void (*destroy)(Class List *this); //销毁
void (*clear)(Class List *this); //清空表中所有元素
Boolean (*isEmpty)(Class List *this); //判断表是否为空
Object (*get)(Class List *this,int index); //获取第index个元素的值
Status (*insert)(Class List *this,int index,Object value); //在index处插入一个元素
Status (*delete)(Class List *this,int index); //删除index处的元素
};
PS:其实(链式表专用)和(数组表专用)的那些多余的属性不应该放到List接口来的,只是当初刚刚有这个方面的灵感的时候没注意考虑到这些。所以留下了这一大败笔。但是我实在也想不通,如果不通过继承,那么如何保证这些属性的私有性,而继承却正是我想极力避免的东西,极度矛盾中.....
有了线性表的接口,下面要实现的就是实现这个接口了。我们打算实现两种线性表:1、数组表,2、链式表。首先我们先实现数组表Class ArrayList
//ArraList.c
void ArrayList_Destroy(Class List *this){
if(this!=Null){
this->clear(this);
free(this);
}
}
void ArrayList_Clear(Class List *this){
int i;
Class Element *e = Null;
if(this!=Null && !this->isEmpty(this)){
for(i=0;i<this->length;i++){
this->delete(this,0);
}
this->elements = Null;
this->length=0;
this->size=this->init_size;
}
}
Boolean ArrayList_IsEmpty(Class List *this){
if(this->elements == Null)
return True;
return False;
}
Object ArrayList_Get(Class List *this,int index){
if(this->isEmpty(this) || index<0 || index>=this->length)
return Null;
return (*(this->elements+index))->value;
}
Status ArrayList_Insert(Class List *this,int index,Object value){
int i;
if(index<0 || index>this->length)
return Fail;
if(this->isEmpty(this))
this->elements = (Class Element**)malloc(sizeof(Class Element*)*this->init_size);
for(i=this->length-1;i>=index;i--)
this->elements[i+1] = this->elements[i];
this->elements[index] = Element_new(value);
this->length++;
if(this->length==this->size){
this->elements = (Class Element**)realloc(this->elements,(this->size+this->increment)*sizeof(Class Element*));
this->size+=this->increment;
}
return Success;
}
Status ArrayList_Delete(Class List *this,int index){
int i;
Class Element *etemp;
if(this->isEmpty(this)==True || index<0 || index>=this->length)
return Fail;
this->elements[index]->destroy(this->elements[index]);
for(i=index;i<this->length;i++)
this->elements[i] = this->elements[i+1];
this->length--;
if(this->length==0){
free(this->elements);
this->elements = Null;
}
return Success;
}
Class List *ArrayList_new(int init_size,int increment){
Class List *this = (Class List*)malloc(sizeof(Class List));
Class Element *e;
int i;
this->length = 0;
this->init_size = init_size;
this->increment = increment;
this->size = init_size;
this->elements = Null;
this->destroy = ArrayList_Destroy;
this->clear = ArrayList_Clear;
this->isEmpty = ArrayList_IsEmpty;
this->get = ArrayList_Get;
this->insert = ArrayList_Insert;
this->delete = ArrayList_Delete;
return this;
}
再来实现一个链式表
void ChainList_Destroy(Class List *this){
if(this!=Null){
this->clear(this);
free(this);
}
}
void ChainList_Clear(Class List *this){
int i;
if(this!=Null && !this->isEmpty(this)){
for(i=0;i<this->length;i++)
this->delete(this,0);
this->length=0;
}
}
Boolean ChainList_IsEmpty(Class List *this){
if(this->length == 0)
return True;
else
return False;
}
Class Element *ChainList_GetElement(Class List *this,int index){
int i;
Class Element *etemp = this->head;
if(this->isEmpty(this) || index<0 || index>this->length)
return Null;
for(i=0;i<=index;i++)
etemp = etemp->next;
return etemp;
}
Object ChainList_Get(Class List *this,int index){
return ChainList_GetElement(this,index)->value;
}
Status ChainList_Insert(Class List *this,int index,Object value){
Class Element *etemp,*element;
if(index<0 || index>this->length)
return Fail;
if(this->length == this->size)
return Fail;
if(this->isEmpty(this)==False)
etemp = ChainList_GetElement(this,index);
else
etemp = this->end;
element = Element_new(value);
etemp->prior->next = element;
element->prior = etemp->prior;
element->next = etemp;
etemp->prior = element;
this->length++;
return Success;
}
Status ChainList_Delete(Class List *this,int index){
Class Element *etemp;
if(this->isEmpty(this)==True || index<0 || index>=this->length)
return Fail;
etemp = ChainList_GetElement(this,index);
etemp->prior->next = etemp->next;
etemp->next->prior = etemp->prior;
etemp->destroy(etemp);
this->length--;
return Success;
}
Class List *ChainList_new(){
Class List *this = (Class List*)malloc(sizeof(Class List));
int i;
this->elements = Null;
this->destroy = ChainList_Destroy;
this->clear = ChainList_Clear;
this->isEmpty = ChainList_IsEmpty;
this->get = ChainList_Get;
this->insert = ChainList_Insert;
this->delete = ChainList_Delete;
this->head = Element_new(Null);
this->end = Element_new(Null);
this->head->prior = Null;
this->head->next = this->end;
this->end->prior = this->head;
this->end->next = Null;
this->length = 0;
return this;
}
能耐心看到这一篇的说明是高手了...那我就懒得写注释了,反正都那么容易...^-^
下面就仅仅做应用举例
#include "const.h"
#include "Element.h"
#include "Element.c"
#include "List.h"
#include "ArrayList.c"
#include "ChainList.c"
//由于不管是ArrayList,还是ChainList,他们所调用的接口是一样的。
//所以show函数可以通过List接口调用他们,当你改变List的实现类型的时候
//可以完全不用修改show里面的内容
void show(Class List *list){
Object temp;
list->insert(list,0,Integer_new(100));
list->insert(list,0,String_new("Hello MM!"));
printf("%d/t",*(Integer)list->get(list,1));
printf("%s/n",(String)list->get(list,0));
temp = list->get(list,0);free(temp);
temp = list->get(list,1);free(temp);
list->destroy(list);
}
int main(void){
Class List *list = Null;
printf("/n<ArrayList>/n");
list = ArrayList_new(100,10);//用数组表实现
show(list);
printf("/n<ChainList>/n");//用链式表的实现
list = ChainList_new();
show(list);
}
输出结果:
<ArrayList>
100 Hello MM!
<ChainList>
100 Hello MM!