第一部分 线性表的顺序存储(二)--动态分配
2011-04-12 00:35
561 查看
(二)线性表的动态分配顺序存储
1. 头文件及宏定义:
2.数据结构定义:
3.基本操作:
以上操作中最后两个函数比较特殊,
int LocateElem(SqList *L,elemtype e,Status(*compare)(elemtype,elemtype))
void ListTraverse(SqList *L,void(*visit)(elemtype *))
特殊在这两个函数的参数 中都有一个 type1(* name)(type2,...,typen)这样的参数,这是用函数做参数的写法,其中name是一个指针形参,name所指向的的数据类型为 一个函数,这个函数的返回类型为type1,参数类型为type2,...,typen.
在调用该类函数时,只要把指定类型的函数的地址当作实参传入即可,也就是函数的名字,不需要加括号。
和形参compare匹配的实参类型,如myequle,IsSquare定义如下:
调用:
LocateElem(L,e,myequle);
LocateElem(L,e,IsSquare);
//和形参visit匹配的实参类型,如print,inc,定义如下:
4.归并:
本文出自 “十年一剑” 博客,请务必保留此出处http://lhqvip.blog.51cto.com/2211973/542019
1. 头文件及宏定义:
#include<stdio.h> #include<stdlib.h> #define LIST_INIT_SIZE 10 //初始分配量 #define LIST_INCREMENT 2 //分配增量 typedef int elemtype; typedef enum { OK, //0 TRUE, //1 FALSE, //2 ERROR, //3 OVERFLOW, //4 }Status; |
typedef struct { elemtype * elem; //存储空间基址 int length; //当前长度 int listsize; //当前分配的存储容量 }SqList; |
/*构造一个空的顺序线性表*/ void InitList(SqList *L) { L->elem = (elemtype *)malloc(LIST_INIT_SIZE*sizeof(elemtype)); if(L->elem == NULL) exit(OVERFLOW); L->length = 0; L->listsize = 0; } /*销毁顺序线性表*/ void DestroyList(SqList *L) { free(L->elem); L->elem = NULL; L->length = 0; L->listsize = 0; } /*将线性表重置为空表*/ void ClearList(SqList *L) { L->length = 0; } /*判断线性表是否为空表,是返回true,否返回false*/ Status ListEmpty(SqList L) { if(L.length == 0) return TRUE; else return FALSE; } /*返回顺序线性表中元素个数*/ int ListLength(SqList *L) { return L->length; } /*返回第i个元素的值到e*/ Status GetElem(SqList *L,int i,elemtype *e) { if(i<1 || i>L->length) return ERROR; *e = *(L->elem+i-1); return OK; } /*若cur_e是L中的元素,且不是第一个,则用pre_e返回它的前驱*/ Status PriorElem(SqList *L,elemtype cur_e, elemtype * pre_e) { int i; elemtype * p = L->elem+1;//从第二个元素开始判断 for(i=0;i<L->length-1;i++,p++) if(*p == cur_e) break; if(i < L->length-1) *pre_e = *--p; else return ERROR; return OK; } /*若cur_e是L中的元素,且不是最后一个,则用next_e返回它的前驱*/ Status NextElem(SqList *L,elemtype cur_e, elemtype * next_e) { int i; elemtype * p = L->elem; for(i=0;i<L->length-1;i++,p++)//循环到倒数第二个元素 if(*p == cur_e) break; if(i < L->length-1) *next_e = *++p; else return ERROR; return OK; } /*在L中的i个位置之前插入一个新的元素e*/ Status ListInsert(SqList *L,int i,elemtype e) { elemtype *newbase,*q,*p; if(i<1 || i>L->length+1)//listsize必须要比length大才能插入,且插入后必须要使元素的内存连续,所以i可以为length+1 return ERROR; if(L->length == L->listsize) { newbase=(elemtype*)realloc(L->elem,(L->listsize+LIST_INCREMENT)*sizeof(elemtype));//重新分配内存,增加空间 if(!newbase) exit(OVERFLOW); L->elem = newbase; L->listsize += LIST_INCREMENT; } q = L->elem+i-1;//q为插入的位置 for(p = L->elem+L->length-1;p>=q;p--) *(p+1) = *p;//插入位置及之后的所有元素向表尾移动 *q = e; //插入e ++(L->length); return OK; } /*删除L中的第i个数据元素,并用e返回其值*/ Status ListDelete(SqList *L,int i,elemtype *e) { elemtype *p,*q; if(i<1 || i>L->length) return ERROR; q = L->elem+i-1; //要删除的位置 *e = *q; p = L->elem+L->length;//表尾位置 for(++q;q<=p;++q) *(q-1) = *q; //要删除位置之后的所有元素前移一位 L->length--; return OK; } /*返回L中第一个与e满足关系compare()关系的元素的位置*/ int LocateElem(SqList *L,elemtype e,Status(*compare)(elemtype,elemtype)) { int i = 1; elemtype *p = L->elem; while(i<=L->length && !compare(*p++,e)) ++i; if(i<=L->length) return i; else return 0; } /*依次对L中的每一个元素调用函数visit(),来改变每一个元素的值。 对L中的元素用某个关系进行历遍*/ void ListTraverse(SqList *L,void(*visit)(elemtype *)) { elemtype *p = L->elem; int i; for(i=1; i<=L->length; i++,p++) visit(p); } |
int LocateElem(SqList *L,elemtype e,Status(*compare)(elemtype,elemtype))
void ListTraverse(SqList *L,void(*visit)(elemtype *))
特殊在这两个函数的参数 中都有一个 type1(* name)(type2,...,typen)这样的参数,这是用函数做参数的写法,其中name是一个指针形参,name所指向的的数据类型为 一个函数,这个函数的返回类型为type1,参数类型为type2,...,typen.
在调用该类函数时,只要把指定类型的函数的地址当作实参传入即可,也就是函数的名字,不需要加括号。
和形参compare匹配的实参类型,如myequle,IsSquare定义如下:
Status myequle(elemtype c1,elemtype c2) { //判断是否相等 if(c1 == c2) return TRUE; else return FALSE; } Status IsSquare(elemtype a,elemtype b) { //判断a是否是b的平方关系, if(a == b*b) return TRUE; else return FALSE; } |
LocateElem(L,e,myequle);
LocateElem(L,e,IsSquare);
//和形参visit匹配的实参类型,如print,inc,定义如下:
void print(elemtype *c) { printf("%d",*c); } void inc(elemtype *c) { (*c)++; } |
void MergeList(SqList *La,SqList *Lb,SqList *Lc) { elemtype *pa,*pa_last,*pb,*pb_last,*pc; pa = La->elem; pb = Lb->elem; Lc->listsize = Lc->length = La->length+Lb->length; pc = Lc->elem = (elemtype*)malloc(Lc->listsize*sizeof(elemtype)); if(!pc) exit(OVERFLOW); pa_last = pa+La->length-1; pb_last = pb+Lb->length-1; while(pa<=pa_last && pb<=pb_last) { if(*pa<=*pb) *pc++ = *pa++; else *pc++ = *pb++; } while(pa<=pa_last) *pc++ = *pa++; while(pb<=pb_last) *pc++ = *pb++; } |
相关文章推荐
- 动态分配的顺序线性表的十五种操作—C语言实现
- 单链表的顺序实现例程[动态分配存储空间]
- 数据结构之线性表的线性分配动态存储
- 动态分配的顺序线性表的十五种操作—C语言实现
- 动态分配的顺序线性表的十五种操作—C语言实现
- 第一部分 线性表的链式存储(三)--静态链表
- 线性表的顺序动态存储——C语言实现简单函数
- 第一部分 线性表的链式存储(四)--单循环链表
- 第一部分 线性表的链式存储(一)--带头结点
- 第一部分 线性表的链式存储(二)--无头结点
- 线性表之顺序存储
- 线性表顺序存储
- Java数据结构——线性表的顺序存储实现
- [SDUT](3324)顺序表应用1:多余元素删除之移位算法 ---顺序存储(线性表)
- 【数据结构之线性表顺序存储】简单的数组的方式实现
- 动态存储分配
- [SDUT](2116)数据结构实验之链表一:顺序建立链表 ---链式存储(线性表)
- 【C语言探索之旅】 第二部分第八课:动态分配
- C里面的内存动态分配函数与存储类别
- 结构算法 001 线性表的顺序存储--顺序表