线性表

7 篇文章 0 订阅
2 篇文章 0 订阅

在开始本章节之前,我要说明两个问题:

1 线性表的一个误解

很多人认为,并且严老师的书上也是这么划分,就是将线性表和栈,队列划分开来。其实并不是这么回事,我们可以参考《计算机程序设计艺术》第一卷,第二章。其实线性表包括链表,栈,队列。

2 就是我这里想说一些前些天一个女同学问我的一个问题

她大概是这么说的:NULL是什么啊?p = NULL;是什么意思啊?为什么要等于NULL?

我开始一听就有些懵,我不知道怎么样去回答他,后思考了一下,我这样回答了她(也许没这么具体):

NULL就是0.我们在系统中有这么一个定义:

#define  NULL  0

p = NULL;就是我们令p指向0,即不指向任何内存空间.至于我们为什么这么做呢?其实就是为我们以后的判断做基础的。

;若我们不定义p = NULL;也就是说我们不引入NULL.你该如何去遍历一个链表呢?该如和判断一个链表已经结束呢。当然我们可以用length做个计数。但我们无法从指针层面做一个判断了。为什么呢?因为我们定义一个指针,如:int *p;

此时p指向何处我们并不清楚,当然很大程度上编译器会为我们初始化为0,但我们不敢保证。所以我们最好引入一个NULL。作为判断标志。

 

好的,下面我们正式开始本章节;

这里我们对于线性表也就是用本书的说法了.

线性表的顺序表示和实现

线性表的顺序表示,即元素是存储在一段连续的内存空间之中的,至于这段空间到底需要多大,我们并不知道,我们只能先给他分配一定的内存空间,而后需要的时候再增加分配即可。

对于定义分配空间的初始分配量和增量,我们可以使用宏来完成此任务,为什么要使用宏来完成呢?

1 考虑的程序的清晰性与可读性

2 考虑到以后修改时的方便性

现在我们对顺序链表做一个定义:

#define LIST_INIT_SIZE 100

#define LISTINCREMENT 10

typedef int ElemType;

typedef int Status;

enum {OVERFLOW,OK};

typedef struct

{

    ElemType *elem; //链表存储空间的基地址

    int length; //链表当前长度

    int listsize; //链表的分配空间大小

}SqList;

然后我们按照说上给定的操作一一为它定义:

 

#include "stdio.h"

#define LIST_INIT_SIZE 100

#define LISTINCREMENT 10

typedef int ElemType;

typedef int Status;

enum {ERROR,OVERFLOW = 0,OK};

typedef struct

{

    ElemType *elem; //链表存储空间的基地址

    int length; //链表当前长度

    int listsize; //链表的分配空间大小

}SqList;

Status InitList(SqList *L)

{

    L->elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));

    if (!L->elem)

    {

       exit(OVERFLOW);

    }

    L->length = 0;

    L->listsize = LIST_INIT_SIZE;

    return OK;

}

Status DestroyList(SqList *L)

{

    if (L->elem)

    {

        free(L->elem);

    }

    L->elem = NULL;

    L->length = 0;

    L->listsize = 0;

    return OK;

}

Status ClearList(SqList *L)

{

    L->length = 0;

    return OK;

}

Status ListEmpty(SqList L)

{

    if (0 == L.length)

    {

       return ERROR;

    }

    return OK;

}

int ListLength(SqList L)

{

    return L.length;

}

Status GetElem(SqList L,int i,ElemType *e)

{

    if (i <= 0 || i >= L.length)

    {

       printf("ilegle position : %d(i)",i);

       return ERROR;

    }

    *e = L.elem[i-1];

    return OK;

}

int LocateElem(SqList L,ElemType e,Status (*compare)(ElemType lhs,ElemType rhs))

{

    int i;

    for (i = 0; i < L.length; ++i)

    {

       if (compare(e,L.elem[i]))

       {

           return i+1;

       }

    }

    return 0;

}

void PriorElem(SqList L,ElemType cur_e,ElemType *pre_e)

{

    int i;

    for (i = 0; i < L.length; ++i)

    {

       if (cur_e == L.elem[i])

       {

           if (i == 0)

           {

              printf("%d位于第一个位置,它没有前驱/n",cur_e);

              return;

           }

           return;

       }

       *pre_e = L.elem[i];

    }

}

void NextElem(SqList L,ElemType cur_e,ElemType *next_e)

{

    int i;

    for (i = 0; i < L.length; ++i)

    {

       if (cur_e == L.elem[i])

       {

           if (i == L.length-1)

           {

              printf("%d位于最后一个位置,它没有后继./n",cur_e);

              return;

           }

           *next_e = L.elem[i+1];

           return;

       }

    }

}

void ListInsert(SqList *L,int i,ElemType e)

{

    int j;

    if (L->length == 0)

    {

       L->elem[0] = e;

       ++L->length;

       return;

    }

    if (i <= 0 || i > L->length)

    {

       printf("ilegle position %d(i)/n",i);

       return;

    }

    if (L->length == L->listsize)

    {

       L->elem = (ElemType*)realloc(L->elem,(LIST_INIT_SIZE + LISTINCREMENT) * sizeof(ElemType));

       if (!L->elem)

       {

           exit(OVERFLOW);

       }

       L->listsize += LISTINCREMENT;

    }

    for (j = L->length-1; j >= i-1; --j)

    {

       L->elem[j+1] = L->elem[j];

    }

    L->elem[++j] = e;

    ++L->length;

}

void ListDelete(SqList *L,int i,ElemType *e)

{

    int j;

    if (i <= 0 || i > L->length)

    {

       printf("ilegle position.%d(i)/n",i);

       return;

    }

    *e = L->elem[i-1];

    for (j = i; i < L->length; ++i)

    {

       L->elem[i-1] = L->elem[i];

    }

    --L->length;

}

void ListTraverse(SqList L,void (*visit)(ElemType e))

{

    int i;

    if (L.length == 0)

    {

       printf("Empty List./n");

       return;

    }

    for (i = 0; i < L.length; ++i)

    {

       visit(L.elem[i]);

    }

}

void visit(ElemType e)

{

    printf("%d ",e);

}

Status compare(ElemType lhs,ElemType rhs)

{

    if (lhs == rhs)

    {

       return OK;

    }

    return ERROR;

}

int main()

{

    SqList L;

    int i;

    ElemType e;

    InitList(&L);

    for (i = 0; i < 10; ++i)

    {

       ListInsert(&L,1,i);

    }

    for (i = 0; i < 10; ++i)

    {

       ListDelete(&L,1,&e);

    }

    //DestroyList(&L);

    ListTraverse(L,visit);

    //GetElem(L,2,&e);

    //PriorElem(L,3,&e);

    //NextElem(L,7,&e);

    printf("/n%d",LocateElem(L,5,compare));

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值