(数据结构第二章)线性表的实现
2015-04-10 22:22
309 查看
///顺序表::: #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #define ERROR -1 #define bool char #define ture 1 #define false 0 #define OVERFLOW -2 #define OK 1 #define LIST_INIT_SIZE 100 ///线性表存储空间的初始分配量 #define LISTINCREMENT 10 ///线性表存储空间分配增量 ///说明开始向全用c写,太鸡巴麻烦了,还是换c++吧 typedef struct { int *elem; /// 存储空间基址 int length; /// 当前长度 int listsize; /// 当前分配的存储容量(以sizeof(int)为单位) }SqList; bool InitList_Sq(SqList* L) /// 构造一个空的线性表L { (*L).elem = (int *)malloc(LIST_INIT_SIZE * sizeof(int)); if(!(*L).elem) exit(OVERFLOW); /// 存储分配失败 (*L).length = 0; /// 当前长度,当前为空表,0 (*L).listsize = LIST_INIT_SIZE; /// 初始化存储容量 return OK; }//InitList_Sq void Scanf_Sq(SqList &L,int n) { /// 输入n个值放入顺序表 printf("请输入顺序表:"); for(int i=0;i<n;i++) scanf("%d",&L.elem[i]); L.length = n; return ; } void Printf_Sq(SqList &L) { /// 输出整个顺序表,用2个空格隔开 printf("顺序表为:"); for(int i=0;i<L.length;i++) printf("%d ", L.elem[i]); printf("\n"); } void DestroyList(SqList &L) { /// 销毁线性表 if(L.elem) /// 如果L.elem里分配了值的话 free(L.elem); L.elem = NULL; return; } void ClearList(SqList &L) { /// 将L置为空表 if(L.length) L.length = 0; return ; } bool ListEmpty(SqList L) { /// 判空 /// 若L为空表,返回true,否则返回false return !L.length; } int ListLength(SqList L) { /// 返回L中数据元素的个数 return L.length; } bool GetElem(SqList L,int i,int &e) { /// 1<=i<=ListLength(L) /// 用e返回L中的第i个数据元素 if( 1 <= i || i <= L.length){ e = L.elem[i-1]; return OK; } else return false; } bool ListInsert_Sq(SqList &L, int i, int e) { ///在顺序线性表L中第i个位置之前插入新的元素e ///i的合法值为1<=i<=ListLength_Sq(L)+1 if(i < 1 || i > L.length + 1) return ERROR; ///i值不合法 if(L.length >= L.listsize){ /// 当前存储空间已满增加分配 int *newbase = (int *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(int) ); if(!newbase) exit(OVERFLOW); ///存储分配失败 L.elem = newbase; ///新基址 L.listsize += LISTINCREMENT; ///增加存储容量 } int *q = &(L.elem[i-1]); ///注意,顺序表和数组一样,i个元素是L.elem[i-1] for(int *p = &(L.elem[L.length-1]); p>=q ;p--) *(p+1) = *p; /// 插入位置级及后的元素右移 *q = e; /// 插入e L.length += 1; /// 表长增长1 return OK; } bool PriorElem(SqList L, int cur_e, int & pre_e) { /// 返回cur_e的前趋 /// 若cur_e是L的数据元素,且不是第一个,用pre_e返回它的前驱 for(int i=1;i<L.length;i++) if(L.elem[i] == cur_e) { pre_e = L.elem[i-1]; return OK; } return false; } bool NextElem(SqList L, int cur_e, int & next_e) { /// 返回cur_e的前趋 /// 若cur_e是L的数据元素,且不是最后一个,用pre_e返回它的后继 for(int i=0;i<L.length-1;i++) if(L.elem[i] == cur_e) { next_e = L.elem[i+1]; return OK; } return false; } bool ListDelete_Sq(SqList &L, int i, int &e) { /// 在顺序线性表L中删除第i个元素,并用e返回其值 /// i的合法范围1<=i<=ListLength_Sq(L) if(i < 1 || i > L.length) return ERROR; /// i值不合法 int *p = &(L.elem[i-1]); /// p为被删除元素的位置 e = *p; /// 被删除元素的值赋给e int *q = L.elem + L.length -1; /// 表尾元素的位置 for( p++ ; p<=q ;p++) *(p-1) = *p; /// 被删除之后的元素左移 L.length--; /// 表长减1 return OK; } bool compare(int a,int b){ return a>b; } int LocateElem_Sq(SqList &L, int e, bool (* compare)(int ,int ) ) { /// 在顺序表L中查找第一个值与e满足compare()的元素的位序 /// 若找到返回位序,否则返回0 int i = 1; ///i的初值,为第一个元素的位序 int * p = L.elem; /// p的初值为第一个元素的存储位置 while (i <= L.length && !(* compare)(*p++,e)) ++i; if(i <= L.length) return i; return 0; }// LocateElem_Sq void MergeList_Sq(SqList La, SqList Lb, SqList &Lc) { /// 已知顺序表La和Lb的元素按值非递减排列 /// 归并La和Lb得到的新的顺序表Lc,Lc的元素也是按非递减排列的 int *pa = La.elem, *pb = Lb.elem; Lc.listsize = Lc.length = La.length + Lb.length; int *pc = Lc.elem = (int *)malloc(Lc.listsize*sizeof(int)); if(!Lc.elem) exit(OVERFLOW); /// 存储分配失败 int *pa_last = La.elem + La.length -1; int *pb_last = Lb.elem + Lb.length -1; while(pa <= pa_last && pb <= pb_last){ /// 归并 if(*pa <= *pb) *pc++ = *pa++; else *pc++ = *pb++; } while(pa <= pa_last) *pc++ = *pa++; /// 插入La中的剩余元素 while(pb <= pb_last) *pc++ = *pb++; /// 插入Lb中的剩余元素 return ; }// MergeList_Sq bool visit(int &x) { x+=1; return OK; } bool ListTraverse(SqList L, bool visit(int & x)) { /// 依次对L的每个数据元素调用visit(),一旦visit()调用失败,操作失败 /// 我写的是对每个元素进行+1操作 for(int i=0;i<L.length;i++) if( !(* visit )( L.elem[i] ) ) return false; return OK; } bool Equal(int a,int b){ return a== b; } void union_Sq(SqList &La, SqList Lb) { /// 将所有线性表Lb中的但不在La中的数据元素插入到La中 int cur_e=0; int La_len = ListLength(La), Lb_len = ListLength(Lb); ///求线性表的长度 for(int i=1;i<=Lb_len;i++){ GetElem(Lb,i,cur_e); /// 驱Lb中第i个元素赋给e if(!LocateElem_Sq(La,cur_e,Equal)) ListInsert_Sq(La, ++La_len,cur_e); /// La中不存在和e相同的数据元素,则插入 } }//union void MergeList(SqList La, SqList Lb, SqList &Lc) { /// 已知线性表La和Lb中的元素按非递减排列 /// 归并La和Lb得到新的线性表Lc,Lc的数据元素也按非递减排列 InitList_Sq(&Lc); int i = 1,j = 1, k = 0; int ai =0, bj = 0; int La_len = ListLength(La), Lb_len = ListLength(Lb); while( (i<=La_len) && (j <= Lb_len) ){ /// La和Lb均为非空 GetElem(La,i,ai); GetElem(Lb,j,bj); if(ai <= bj) { ListInsert_Sq(Lc, ++k, ai); ++i; } else { ListInsert_Sq(Lc, ++k, bj); ++j; } } while(i <= La_len) { GetElem(La,i,ai); ListInsert_Sq(Lc, ++k, ai); ++i; } while(j <= Lb_len) { GetElem(Lb,j,bj); ListInsert_Sq(Lc, ++k, bj); ++j; } }//MergeList int main() { SqList L; /// 定义一个顺序表 InitList_Sq(&L); ///初始化顺序表L printf("请输入需要输入顺序表的个数n:"); int n; scanf("%d",&n);/// Scanf_Sq(L,n);/// 从0开始读入n个顺序表 Printf_Sq(L); /// 输出当前的顺序表 printf("\n"); /// 测试插入 ListInsert_Sq(L,6,6); Printf_Sq(L); printf("\n"); /// 测试删除 int e; ListDelete_Sq(L,6,e); Printf_Sq(L); printf("被删除的元素是:%d\n",e); printf("\n"); /// 测试第一个与e大或者小的数,返回其位序 printf("请输入要判断位序的e:"); scanf("%d",&e); printf("%d\n",LocateElem_Sq(L,e,compare) ); printf("\n"); ///测试归并 SqList Lc,Lb; InitList_Sq(&Lb); InitList_Sq(&Lc); printf("请输入需要输入顺序表Lb的个数n:"); scanf("%d",&n); Scanf_Sq(Lb,n); MergeList_Sq(L,Lb,Lc); Printf_Sq(Lc); DestroyList(Lb); DestroyList(Lc); printf("\n"); ///测试前驱,后继 int pre_e,next_e,cur_e; printf("请输入要判断前驱后继的cur_e:"); scanf("%d",&cur_e); if( PriorElem(L,cur_e,pre_e) ) printf("%d的前驱是:%d\n",cur_e,pre_e); else printf("该元素没有前驱\n"); if( NextElem(L,cur_e,next_e) ) printf("%d的后继是:%d\n",cur_e,next_e); else printf("该元素没有后继\n"); /// 测试visit() ListTraverse(L, visit); Printf_Sq(L); ///测试Clear和Empty和Length和GetElem int i; printf("请输入i:"); scanf("%d",&i); if( GetElem(L,i,e) ) printf("第%d个元素是%d\n",i,e); else printf("该角标%d不在范围内\n",i); printf("当前表长度为:%d\n",ListLength(L)); ///测试union InitList_Sq(&Lb); printf("输入集合B的个数n:\n"); scanf("%d",&n); Scanf_Sq(Lb,n); union_Sq(L,Lb); Printf_Sq(L); printf("\n"); /// 测试MergeList MergeList(L, Lb, Lc); Printf_Sq(Lc); ///清空表 printf("下面进行清空表操作\n"); ClearList(L); if(ListEmpty(L)) printf("L为空表\n"); else printf("L不是空表\n"); printf("\n"); DestroyList(L); printf("TO BE END\n"); return 0; } ///调试过程中出现了Bug ///DestroyList(Lb)和DestroyList(Lc)都出现了错误 ///找了一番竟然是没有初始化,但是没初始化竟然能用,就是销毁的时候错了 ///没初始化,L.elem里应该没有值吧,那就是越界访问了,if(L.elem)怎么又能进去呢
相关文章推荐
- 数据结构 第二章 线性表(1)顺序线性表的实现
- 严蔚敏版《数据结构》第二章线性表的算法C语言实现
- 数据结构第二章之线性表C实现
- 数据结构(C语言版)第二章顺序线性表的实现
- 算法与数据结构--实现线性表的删除操作--算法2.4
- 数据结构:线性表的链式存储(双向链表)--Java实现
- javascript实现数据结构:线性表--简单示例及线性表的顺序表示和实现
- 数据结构3:线性表的静态链表的表示和实现
- 2008秋季-计算机软件基础-第二章 线性数据结构(PPT课件)
- 数据结构--线性表(顺序实现,链式实现,多项式计算)
- 数据结构:线性表的顺序存储--Java实现
- 数据结构队列的java实现,包括线性和链式两种方式
- 数据结构-----线性表的顺序表示与实现
- 数据结构:线性表(顺序存储)顺序表类(实现顺序表的创建,输出,插入,删除功能)
- 算法与数据结构--实现线性表的合并操作(合并后按非递减排列)--算法2.6
- 数据结构:线性表的链式存储(单向链表)--Java实现
- 第二章、线性表的顺序表示和实现
- java数据结构:线性表之数组实现
- 【数据结构】线性表的单链表存储结构表示和实现
- 数据结构------线性表的链式表示与实现