Data|[转载] 线性表的数组实现

/*对于线性结构,有两种保存的方法,一种是使用C语言中内置的数组,这样的结构成为顺序表;另一种使用指针,这样的结构成为链表。对于线性结构,有12种基本的操作,分别是:初始化、删除、清空、判断是否为空、遍历、求表的长度、求某个元素在表中的位置、返回特定序号的元素、求某个元素的前一个元素、求某个元素的后一个元素、插入一个元素、删除一个元素。这一小节介绍如何利用数组实现线性表。*//*再插入元素时,如果线性表已满,需要重新分配内存空间,新分配的内存空间设定为原来的2倍。这个倍数也不是我随便给出的,我是参考C++中STL里面的vector给出的。相信那些专家,肯定考虑了倍数过小而导致多次分配内存与内存分配太大的折中*/#include #include typedef int Elementtype; typedef struct arraylist { Elementtype *Array; //实际存放元素的数组 int length; //数组中已经使用了多少元素 int size; //数组的容量 } ; //初始化顺序表:给出初始化长度 bool InitialArray(arraylist *arrayList,int len) { arrayList->length = 0; arrayList->size = len; arrayList->Array = (Elementtype*)malloc(len*sizeof(Elementtype)); if(NULL == arrayList->Array) return false; else return true; }//删除顺序表 void DeleteArray(arraylist *arrayList) { arrayList->length = 0; arrayList->size = 0; free(arrayList->Array); arrayList->Array = NULL; }//清空顺序表 void ClearArray(arraylist *arrayList) { arrayList->length = 0; }//判断是否为空 bool Empty(arraylist *arrayList) {if(0 == arrayList->length) { printf("the arrayList is empty!\n"); return true; } else { printf("the arrayList is not empty!\n"); return false; } }//求有多少个元素 int ArrayLength(arraylist *arrayList) { return arrayList->length; }//取出某个元素 bool GetElement(arraylist *arrayList,int index,Elementtype *element)//元素取出用指针 { if(index < 0 || index > ArrayLength(arrayList)-1) //数组越界 return false; else { *element = arrayList->Array[index]; return true; }}//遍历顺序表,并打印 void PrintArray(arraylist *arrayList) { printf("array elements are: "); for(int i = 0; i < ArrayLength(arrayList); ++i) { printf("%d\t",arrayList->Array[i]); } printf("\n"); }//判断某个元素的位置 int LocateElement(arraylist *arrayList,Elementtype element) { for(int i = 0; i < ArrayLength(arrayList); ++i) { if(element == arrayList->Array[i]) return i; } return -1; }//求某个元素的前驱:如果没找到返回-2;如果是第一个元素。返回-1;否则返回前驱元素的下标 int PreElement(arraylist *arrayList,Elementtype element,Elementtype *preElement) { for(int i = 0 ; i < ArrayLength(arrayList); ++i) { //如果找到了 if(element == arrayList->Array[i]) { //如果是第一个元素 if(0 == i) { return -1; } else { *preElement = arrayList->Array[i-1]; return i-1; } } } return -2; }//求某个元素的后继:如果没找到,返回-2,如果是最后一个元素,返回-1;否则返回后继元素的下标 int NextElement(arraylist *arrayList,Elementtype element,Elementtype *nextElement) { for(int i = 0; i < ArrayLength(arrayList); ++i) { if(element == arrayList->Array[i]) { if(ArrayLength(arrayList) -1 == i) { return -1; } else { *nextElement = arrayList->Array[i+1]; return i+1; } } } return -2; }//将元素插入到指定位置 bool InsertElem(arraylist *arrayList,int index ,Elementtype element ) { //先判断插入位置是否合法 if(0 > index ||ArrayLength(arrayList) < index) return false; //先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照 newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动 释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。 //如果顺序表存储空间已满,则需要重新分配内存 if(arrayList->length == arrayList->size) { arrayList->Array = (Elementtype*)realloc(arrayList->Array,2*arrayList->size*sizeof(Elementtype)); if(NULL == arrayList->Array) //分配失败,程序退出 return false; else //分配成功,扩容 arrayList->size *= 2; } //将插入点之后的元素后移 for(int i = ArrayLength(arrayList); i > index; --i) arrayList->Array[i] = arrayList->Array[i-1]; //插入元素 arrayList->Array[index] = element; //顺序表长度自增 ++arrayList->length; return true; }//删除指定位置的元素 bool DeleteElem(arraylist *arrayList,int index ,Elementtype *element) { if(index < 0 || index > ArrayLength(arrayList)-1) return false; *element = arrayList->Array[index]; //将删除点的元素依次左移 for(int i = index; i < ArrayLength(arrayList); ++i) { arrayList->Array[i] = arrayList->Array[i+1]; } --arrayList->length; ; return true; }/*我们可以看出,利用数组来表示线性结构,最大的优点在于由于数组是连续储存的,所以随机访问速度非常快,只需要用数组的首地址+下标*sizeof(结构体)就能计算指定元素的地址了。而它的缺点也很明显:就是插入、删除时效率很低,因为要移动大量的元素,甚至需要重新分配内存。*/


    推荐阅读