数据结构——第二讲、线性结构(2)

来源:互联网 发布:数码绘画软件 编辑:程序博客网 时间:2024/05/17 22:50

2.1.2 线性表及存储结构

1、什么是线性表
同类型数据元素构成有序序列的线性结构。个数叫长度,没有元素时叫空表,起始位置叫表头,结束位置叫表尾。

2、线性表的抽象数据类型描述(想象成一个线性表类,包括数据和操作)
类型名称:线性表(List)
数据对象集:线性表是n(>=0)个元素构成的有序序列
操作集:L表示线性表,x表示元素,整数i表示位置,从1开始计算

List MakeEmpty()                        //1、初始化一个空表ElementType FindK(int K, List L)        //2、找线性表中的第K个元素并返回int Find(ElementType x, List L)         //3、返回元素x在线性表L中的位置void Insert(Element x, int i, List L)   //4、在第i个元素之前插入元素xvoid Delete(int i,List L)               //5、删除第i个元素int Length(list L)                      //6、返回线性表的长度

3、线性表的存储方式
1)、顺序存储方式
利用数组连续存储,下标从0到n-1,存a1到an,线性表长度正好是最后一个元素的下标加1.

typedef struct LNode *Liststruct LNode{    ElementType Data[MAXSIZE];   //ElementType类型的数组存数据    int last;                    //最后一个元素的下标}L;                              //实例化一个线性表LList PtrL;                   //或者一个LNode类型的指针//L.Data[i]或PtrL->Date[i],访问某一个元素//L.last+1或PtrL->last+1,获得线性表长度

用上述顺序存储结构实现操作集的主要操作

创建一个空链表,初始化,MakeEmpty()

//注意,List是上面定义的struct LNode *List,是一个结构体指针List MakeEmpty(){    //声明一个LNode类型的指针    List PtrL;    //malloc表示分配特定长度的内存,按字节计,sizeof用来获取LNod类型所需空间    //把PtrL指向这个申请好的空间    PtrL = (List)malloc(sizeof(LNode));    //把last设为-1,使长度为last+1=0    Ptrl->last = -1;    return PtrL;}

查找某个特定元素,Find()

int Find(ElementType x, List PtrL){    for(int i = 0; i <= PtrL->last; i++){        if(PtrL->Data[i] == x) return i;    }    return -1;}

插入,Insert()

//每次都打PtrL太麻烦了,换成L吧……void Insert(ElementTpye x, int i, List L){    if(L->last==MAXSIZE-1){        printf("表满!");        return;    }    //不能在标号为0(即i为1)的位置前面再插,但是可以在last+1(即i为last+2)的位置插入,算添加一个元素。    if(i<1 || i>L->last+2){        printf(""位置不合法!);        return;    }    //第i个元素的下标是i-1,把i-1的位置空出来给新元素    for(int k = L->last; k>=i-1; k--){        L->Data[k+1] = L->Data[k];    }    L->Data[i-1] = x;    L->last++;}

删除,Delete(),删除第i个元素(位置i-1)

void Delete(int i, List L){    if(i<1 || i>L->last+1){        printf("位置不存在");        return;    }    for(int j = i-1; j<last; j++)        L->Data[j] = L->Data[j+1];    L->last--;}

2)、链式存储方式(不需要物理上相邻)
每一个节点都是一个结构体,顺序存储每一个链表是一个结构体

typedef struct LNode *Liststruct LNode(){    ElementType Data;    List NEXT;}struct LNode L;List PtrL;

求表长,Length()

int Length(List PtrL){    int j = 0;    List p = PtrL;    while(p){          //p为NULL时,循环会退出        p=p->NEXT;        j++;    }    return j;}

序号K查找,FindK()

List FindK(int K, List PtrL){    List p = PtrL;    int i = 1;    while(p != NULL && i < K){        p = p->NEXT;        i++;    }    if(i == K)        return p;    else        return NULL;}

查找某个元素对应的节点(不是某个元素的序号),Find()

List Find(ElementType x, List PtrL){    List p = PtrL;    while(p != NULL && p->Data != x){        p=p->NEXT;    }    return p;}

插入Insert(),插在第i个位置,即插在第i-1个位置的后面

List Insert(ElementType x, int i, List PtrL){    List p = (List)malloc(sizeof(struct LNode));    p->Data = x;    if(i == 1){        p->NEXT = PtrL;        return p;    }    s = FindK(i-1,PtrL);    if(!s){        printf("参数i错误");        return NULL;    }else{        p->NEXT = s->NEXT;        s->NEXT = p;        return PtrL;    }}

删除Delete(),删除第i个节点

List Delete(int i, List PtrL){    List p;    if(i == 1){        p = PtrL;        if(PtrL!=NULL)            PtrL = PtrL->NEXT;        else            return NULL;        free(p);        return PtrL;    }    p = FindK(i-1,PtrL);    if(p == NULL || p->NEXT == NULL){        printf("找不到参数");        return NULL;    }else{        List s = p->NEXT;        p->NEXT = s->NEXT;        free(s);        return PtrL;    }}