线性表的顺序表示和实现

  1 # ifndef _TEST_H_
  2 # define _TEST_H_
  3 # include <stdio.h>
  4 # include <stdlib.h>
  5 # include <stdbool.h>
  6 # define LIST_INIT_SIZE 10     //线性表存储空间初始分配
  7 # define LIST_INCREMENT 2       //线性表存储空间空间分配增量
  8 # define ERROR 0                //失败
  9 # define OK 1                   //成功
 10 
 11 typedef int ElemType; //    抽象数据类型    
 12 typedef int Status;
 13 
 14 typedef struct sqlist
 15 {
 16     ElemType * elem;        //存储空间基址
 17     int length;             //连表元素个数
 18     int listsize;           //但前分配空间个数
 19 }SqList;
 20 
 21 
 22 # endif
  • 文件名为:test.h的头文件

 

 1 # include "test.h"
  2 
  3 
  4 void InitList(SqList * L)       //构造一个空的线性表L
  5 {
  6     L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType) * 10);
  7     if(!L->elem)        //内存分配失败
  8         exit(1);
  9     L->length = 0;      //空表长度为0
 10     L->listsize = LIST_INIT_SIZE;       //初始存储容量
 11 }
 12 
 13 bool ListInsert(SqList * L, int i, ElemType e)
 14 {
 15     ElemType * newbase, *p, *q;
 16     if(i < 1 || i > L->length + 1)  //i的值不合法
 17         return false;
 18 
 19 
 20     if(L->length == L->listsize)    //但前存储空间已满,增加分配
 21     {
 22         newbase = (ElemType *)realloc(L->elem,sizeof(ElemType) * 10 + 2);
 23         if(!newbase)        //存储空间分配失败
 24             exit(1);
 25         L->elem = newbase;
 26         L->listsize += LIST_INCREMENT; //增加存储容量
 27     }
 28 
 29     p = L->elem + i - 1;        //p为插入位置
 30 
 31     for(q = L->elem + L->length - 1; q >= p; q--)       //插入位置之后的元素往右移
 32         *(q+1) = *q;
 33 
 34     *p = e;                     //插入e
 35     L->length++;                //表长增1
 36     return true;
 37 }
 38 
 39 void print(ElemType c)      //以十进制输出元素
 40 {
 41     printf("%d ", c);
 42 }
 43 
 44 void TraverseList(SqList * L, void(*visit)(ElemType))   //线性表存在;对每个元素依次调用visit函数
 45 {
 46     ElemType *p = L->elem;      //p指向第一个元素
 47     int i;
 48 
 49     for(i = 1; i <= L->length; i++)     //从表第一个元素到最后一个元素
 50         visit(*p++);        //对每一个元素调用visit
 51 
 52     printf("\n");
 53 }
 54 
 55 int ListLength(SqList  L)           //返回L表中元素的个数
 56 {
 57     return L.length;
 58 }
 59 
 60 void ListClear(SqList * L)          //顺序线性表存在 ,将L表置成空表
 61 {
 62     L->length = 0;
 63 }
 64 
 65 void DestroyList(SqList * L)
 66 //顺序线性表已存在, 销毁线性表L
 67 {
 68     free(L->elem);          //释放L.elem所指向的存储空间
 69     L->elem = NULL;         //L.elem不再指向任何存储单元
 70     L->length = 0;
 71     L->listsize = 0;
 72 }
 73 
 74 bool ListEmpty(SqList * L)      //检测L链表是否为空 空返回true 不空返回false
 75 {
 76     if(L->length == 0)
 77         return true;
 78     else
 79         return false;
 80 }
 81 
 82 bool GetElem(SqList * L, int i, ElemType * e)   //用e返回l中第i个元素
 83 {
 84     if(i<1 || i > L->length)        //i不再L表的范围之内
 85         return false;
 86 
 87     *e =  *(L->elem+i-1);       //将L表中的第i个值赋给e
 88     return true;
 89 }
 90 
 91 bool equal(ElemType c1, ElemType c2)    //判断俩者关系是否相等 是true 否false
 92 {
 93     if(c1 == c2)
 94         return true;
 95     else
 96         return false;
 97 }
 98 
 99 bool sq(ElemType c1, ElemType c2)       //判断平方关系。
100 {
101     if(c1 == c2 * c2)
102         return true;
103     else
104         return false;
105 }
106 
107 Status LocateElem(SqList * L, ElemType e, bool(*compare)(ElemType, ElemType))   //返回L中满足关系xompare数据元素的位序
108 {
109     ElemType * p = L->elem;     //p的初始值为第一个元素的位置
110     int i = 1;          //i的初始值为第一个元素的位序
111 
112     while(i <= L->length && !compare(*p++, e))  //i没有超出L表范围且 未找到满足关系的数据元素
113         i++;            //继续向后找
114 
115     if(i <= L->length)      //找到满足关系的数据元素
116         return i;       //返回其位序
117     else
118         return 0;       //未找到满足关系的元素
119 }
120 
121 Status PriorElem(SqList * L, ElemType cur_e, ElemType * pre_e)
122 //若cur_e是L的元素且不是第一个则返回前驱,否则操作失败
123 {
124     ElemType * p = L->elem+1;   //p指向第二个元素
125     int i = 2;                  //  从第二个元素开始
126 
127     while(i <= L->length && *p != cur_e)    //i未超出表的范围且未找着以cur_e的元素
128     {
129         p++;            //  p指向下一个元素
130         i++;            //  计数器加1
131     }
132 
133     if(i > L->length)   //到表结束处还未找到值为cur_e的元素
134         return ERROR;   //操作失败
135     else            //找到值为cur_e的元素,并由p指向
136     {
137         *pre_e = *--p;      //把指向p的前一个元素赋值给Pre_e(前驱)
138         return OK;          //操作成功
139     }
140 }
141 
142 Status NextElem(SqList * L, ElemType cur_e, ElemType * next_e)
143 //若cur_e是L的元素且不是最后一个则返回后驱,否则操作失败
144 {
145     int i = 1;          //从第一个元素开始
146     ElemType * p = L->elem; //p指向第一个元素
147 
148     while(i < L->length && *p != cur_e) //i到表尾未找到值为cur_e的元素
149     {
150         i++;    //技术驱加1
151         p++;    //p指向下一个元素
152     }
153 
154     if(i == L->length)  //到表尾的前一个元素还未找到值为cur_e的元素
155         return ERROR;   //操作失败
156     else        //  找到值为cur_e的元素,并由p指向
157     {
158         *next_e = *++p; //p把后继元素赋给next_e
159         return OK;      //操作成功
160     }
161 }
162 
163 Status ListDelete(SqList * L, int i, ElemType * e)
164 {
165     ElemType * p, *q;
166     if(i < 1 || i > L->length)
167         return ERROR;   //i的值不合法
168 
 169     p = L->elem + i -1; //p指向要删除的元素地址
170     *e = *p;            //将要删除的元素赋给e
171     q = L->elem + L->length -1;  //q指向L元素的最后一个地址
172     for(p++; p <= q; p++)   //被删除位置之后向左移动到最后一个
173         *(p-1) = *p;
174     L->length--;    //长度减1
175     return OK;      //操作成功
176 }
                                                                                                                 
  •  文件为:text.c的原代码文件

 

 1 # include <stdio.h>
  2 # include "test.h"
  3 
  4 void print(ElemType c);
  5 void equal(ElemType, ElemType);
  6 bool sq(ElemType, ElemType);
  7 
  8 int main(void)
  9 {
 10     SqList La, Lb;
 11     Status i;
 12     int j, k;
 13     ElemType e, e0;
 14 
 15     InitList(&La);  //初始化线性表La
 16     printf("初始化La后:La.length = %d, La.listsize = %d\n", La.length, Lb.listsize);
 17     for(j = 1; j <= 5; j++)
 18         i = ListInsert(&La, 1, j);  //    在La表头插入元素
 19     printf("在La插入1~5后:*L.elem = ");
 20     for(j = 1; j <= 5; j++)
 21         printf("%d ", *(La.elem+j-1));      //依次输出表中La中的元素
 22     printf("\n调用TraverseList函数再次输出元素");
 23     TraverseList(&La, print);   //依次对La中的元素调用print元素进行输出
 24     i = ListEmpty(La);          //检测是否为空
 25     printf("La.length = %d \t La.listsize = %d\n", La.length, La.listsize);
 26     printf("La.elem = %p, La是否为空i=%d\n", La.elem, i);
 27     ListClear(&La);
 28     i = ListEmpty(La);          //再次检测是否为空
 29     printf("La.length = %d\t La.listsize = %d\n", La.length, La.listsize);
 30     printf("La.elem = %p\t La是否为空i = %d\n", La.elem, i);
 31     for(j = 1; j <= 10; j++)
 32         i = ListInsert(&La, j, j);  //在La表尾插入j
 33     printf("在表尾依次插入1~10后L:");
 34     TraverseList(&La, print);   //依次输出La表中的元素
 35     printf("La.length = %d\t La.listsize = %d\t La.elem = %p\n", La.length, La.listsize, La.elem);
 36     ListInsert(&La,  1, 0);     //在La表头插入0  增加存储空间
 37     printf("在la表头插入0后La.length = %d  La.listsize = %d La.elem = %p\n", La.length, La.listsize, La.elem);
 38     GetElem(&La, 5, &e);  //将La第5个元素赋值给e
 39     printf("La的第5个元素为%d\n", e);
 40     TraverseList(&La, print);
 41     for(j = 10; j <= 11; j++)
 42     {
 43         k = LocateElem(&La, j, equal);  //查找La表中与j相等的元素并将位序赋给k
 44         if(k)   //k不为0表明有符合条件的元素
 45             printf("第%d个值为%d\n", k, j);
 46         else    //k为0没有符合条件的元素
 47             printf("没有值为%d的元素\n",j);
 48     }
 49     for(j = 3; j <= 4; j++)     //测试两个数据
 50     {
 51         k = LocateElem(&La, j, sq); //查找La表中与j的平方相等的元素,并将位序赋给K
 52         if(k)   //k不为0表明有符合条件的元素
 53             printf("第%d个元素的值为%d的平方\n", k, j);
 54         else    //k为0没有符合条件的元素
 55             printf("没有值为%d的平方元素\n", j);
 56     }
 57     for(j = 1; j <= 2; j++) //测试前两个数据
 58     {
 59         GetElem(&La, j, &e0);   //将La中第J个元素赋给e0
 60         i = PriorElem(&La, e0, &e); //求e0的前驱,如成功赋给e
 61         if(i == ERROR)  //操作失败
 62             printf("元素%d无前驱\n", e0);
 63         else            //操作成功
 64             printf("元素%d的前驱为%d\n", e0, e);
 65     }
 66     for(j = ListLength(La) - 1; j <= ListLength(La); j++)//最后两个元素
 67     {
 68         GetElem(&La, j, &e0);   //将La中第J个元素赋给e0
 69         i = NextElem(&La, e0, &e);  //求e0的后驱,如成功赋给e
 70         if(i == ERROR)  //操作失败
 71             printf("元素%d无后继元素\n", e0);
 72         else            //操作成功
 73             printf("元素%d的后继元素为%d\n", e0, e);
 74     }
 75     k = ListLength(La); //求La的表长并赋给k
 76     for(j = k+1; j >= k; j--)
 77     {
 78         i = ListDelete(&La, j, &e);//删除第j个数据
 79         if(i == ERROR)      //操作失败
 80             printf("删除第%d个元素失败\n", j);
 81         else            //操作成功
 82             printf("删除%d个元素成功其值为%d\n", j, e);
 83     }
 84     TraverseList(&La, print); //再次输出表中元素
 85     DestroyList(&La);   //销毁表La
 86     printf("销毁La后L.length = %d L.listsize = %d L.elem = %p\n", La.length, La.listsize, La.elem);
 87 
 88     return 0;
 89 }
  • 文件为:main.c主函数文件

 运行:gcc text.c main.c -o  main   生成main可执行文件  在linux : ./main运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值