线性表-c语言实现(1)

在大学的时候,我只是学了结构,并没有理会具体的实现,最近想写写。

当然,搁置了很久的c有些不太熟练了,还好脑子没坏掉,跟着网页上的写了些 ,除了有些让我吐槽的地方

编译环境 eclipse(c、c++版本),编译器 mingw

另外 我觉得代码实现是能更好的掌握某种结构他是怎么样做这件事情的,在实现之前,还是应该知道线性表做了什么比较好,例如线性表的位置计算可以看作是 中学的等差数列,另外 插入也好 删除也好,自己手写10个数字 如果你要插入 ,删除 怎么样移动,有了思路,实现不是一个大的问题。

写的很糟烂,包含了测试数据,和笔者遇到的坑。

------------------------------------------------

eclipse的这里实在赞,免去了我不少的麻烦 

=========================

1,一些预定义的常量,看心情定义便可,我常常不认识大写的英文。

我非常想要 带编号又复制不上去的那个代码编辑区  不知道怎么做的 。

#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define true 1
#define FALSE 0
#define false 0

#define OK 1
#define ok 1
#define ERROR 0
#define error 0

#define null NULL
#define INFEASIBLE -1
#define infeasible -1
#define OVERFLOW -2
#define overflow -2

#define LIST_INIT_SIZE 10
#define LISTINCREMENT 10

 

2线性表结构体

typedef struct {
    int *elem;   //定义了顺序表中元素类型的数组指针,指向顺序表存储空间的首地址
    int length;       //顺序表的长度(也即元素个数)
    int listsize;     //当前分配给顺序表的存储容量
} SqList;

3初始化线性表 

预先说明  (*L).len等价于L->len

int InitList(SqList *L) {     //初始化线性表list
    L->elem = malloc(LIST_INIT_SIZE * sizeof(int));
    printf(" malloc +++++++ size %d \n ", (int) L->elem);
    if (L->elem == 0) {//判定如果分配不成功则退出
        exit(-1);
    }
    L->length = 0;
    L->listsize = LIST_INIT_SIZE;
    return ok;
}

 

//malloc 初始化空间 转不转换没关系的 你需要的只是这么大的空间而已

这段代码是初始化你定义的结构体,首先按照预定义的空间,我这里面设定的是10,为了做扩充实验。

然后 申请这么大的空间  sizeof(int)是一个int占用的大小,

然后  sizeof(int)×LIST_INIT_SIZE就是10个int的大小,将他们的首地址赋值给L->elem

L->listsize 是这片空间的大小 L->是当前元素的数量

 

4线性表满的判定

int isListSize(SqList *L) {     //判断 队满
    //如果 满了  则0 否则1
    if (L->listsize == L->length) {    //如果分配空间=元素空间=队满
        printf("nonononononononono");
        return 0;
    } else
        return 1;

}

5扩充线性表

int ReList(SqList *L) {     //扩充 list
    printf("************************");
    if (L->elem == 0) {
        exit(error);
    }
    int *q;
    q = realloc(L->elem, (L->listsize + LISTINCREMENT) * sizeof(int));
    printf("\n   this realloc +++++++ size %d \n ", (int) q);
    if (q != null) {
        L->elem = q;
        L->listsize += LISTINCREMENT;
    }
    return ok;
}

 

这里面有一个很赞的方法 realloc ,他会判定如果可以直接扩充,那自然ok ,如果不能 ,则申请新空间,将原有数据复制过去。

 它包含两个参数 realloc(原线性表首地址,新空间大小)

所以千万不要忘记  新空间大小=(L->listsize+ 扩展的大小)×sizeof(int)

另外 需要一个 新地址接收这个 新空间,因为万一有问题 没有赋值上呢?笔者就在这写出了问题。

判定下 没有问题就可以复制了;可以判定 如果q!=null 则执行L->elem=q;L->listsize+=10;

6判定插入位置的合法性

int ispoint(SqList *L, int x) {     //判断插入元素的位置是否合法
    if (x < 0 || x > L->length) {
        printf("x-- point  error\n");
        exit(overflow);
    } else {
        return 1;
    }
}

给定位置x  如果他大于0 或者大于表中已有元素,则退出

讲道理 比如 有10个数据,我指定位置为11 我觉得是合理的,这里我很想写

x>L->length+1

在 后面的插入中 我先判定的是位置,后判定的是空间

感觉 插入 11  然后 现在Length==listsize 然后扩大空间,然后插入 没有任何位置啊 

反而 如果不写  x>L->length+1 我是没办法在 队满的情况下 插入到最后的位置

但是 ,笔者计算位置 用的是 从0开始 所以x>L->length 即可。

7 插入元素

int ListInsert(SqList (*L), int x, int e) {     //向第x个位置前面插入一个元素
    int i = 0;
    ispoint(L, x);     //判断插入位置
    if (isListSize(L) == 0) { //判断队满
        ReList(L);//满了就扩充
    }
    for (i = L->length; i > x; i--) {//移动位置
        L->elem[i] = L->elem[i - 1];
    }
    L->elem[x] = e;//插入数据
    L->length += 1;//更新元素个数
    return ok;
}

我看书上的算法蒙逼了,for处我不知道为什么需要指针,又不是链表。

我想说明 数组即指针!然后 不用那么麻烦。

8删除元素

int ListDel(SqList (*L), int x) {
    int i = 0;
    ispoint(L, x);//判定下删除的位置合法性
    int e = L->elem[x];//先将 元素赋值给 e
    for (i = x + 1; i < L->length; i++) {//挨个移动 覆盖过去
        L->elem[i] = L->elem[i + 1];
    }
    L->length -= 1;//更新元素个数
    return e;//返回删除的元素
}

又一个坑   我才不要写  int  ListDel(SqList (*L),int x, int e)   他要是返回值是 e我也认

你是按照下标删除啊 ,首先 调用的时候 写一个没用的数据

进去了  e 确实赋值了  然后  return OK ~这是在逗我吧。

adt是adt  实现是实现。

9 测试数据

void outlist(SqList *L) {
    int i = 0;
    while (i < L->length) {
        printf("%d\t", (*L).elem[i]);
        i++;
    }
    printf("\n");
}
void inlist(SqList *L, int len) {
    int i = 0;
    while (i < len) {
        L->elem[i] = i;
        L->length += 1;
        i++;
    }
}

int main(void) {
    SqList *list = malloc(sizeof(int));    //看着初始化总是黄色警告心烦
    InitList(list);  
    inlist(list, 10);
    outlist(list);
    printf("1 listsize:%d   2 length :%d  \n", list->listsize, list->length);
    int p = 99;
    ListInsert(list, 10, p);
    printf("1 listsize:%d   2 length :%d  \n", list->listsize, list->length);
    outlist(list);
    printf("this  listdel %d\n", ListDel(list, 5));
    printf("1 listsize:%d   2 length :%d  \n", list->listsize, list->length);
    printf("ok");
    return EXIT_SUCCESS;
}

就是这样  插入是inlist  输出是outlist你要是喜欢 可以 手动插入或者随机数

main里面是测试数据 ;

posted @ 2016-10-10 17:08  toono  阅读(781)  评论(0编辑  收藏  举报