顺序表正是以数组的款型来储存和保管工作节点,顺序表便是以数组的情势来囤积和管理作业节点

功效测试代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "seqlist.h"

typedef struct student{
    char name[20];
    int age;
}student;

int main(int argc, char *argv[])
{
    student stu1,stu2,stu3,stu4,stu5;

    stu1.age = 20;
    stu2.age = 21;
    stu3.age = 22;
    stu4.age = 23;
    stu5.age = 24;

   TSeqList *pslist = (TSeqList*)SeqList_Create(5);

    SeqList_Insert(pslist, (SeqListNode*)&stu1, 0);
    SeqList_Insert(pslist, (SeqListNode*)&stu2, 1);
    SeqList_Insert(pslist, (SeqListNode*)&stu3, 2);
    SeqList_Insert(pslist, (SeqListNode*)&stu4, 3);
    SeqList_Insert(pslist, (SeqListNode*)&stu5, 4);
    printf("length: %d\n",SeqList_Length(pslist));
    SeqList_Traverse(pslist,student,age);

    SeqList_Delete(pslist,2);
    printf("length: %d\n",SeqList_Length(pslist));
    int i;
    student *ptmp = NULL;
    for(i=0; i < SeqList_Length(pslist); i++)
    {   
        ptmp = SeqList_Get(pslist,i);   
        printf("age: %d\n",ptmp->age);
    }
    SeqList_Clear(pslist);
    SeqList_Destroy(pslist);
    return 0;
}

效率函数达成

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "seqlist.h"

//创建并且返回一个空的线性表
SeqList *SeqList_Create(int capacity)
{
    TSeqList *plist = NULL;

    plist = (TSeqList*)malloc(sizeof(TSeqList));
    memset(plist, 0, sizeof(TSeqList));
    if(NULL == plist)
    {
        perror("SeqList_Create TSeqList");
        return NULL;
    }
    plist->pnode = (unsigned int**)malloc(sizeof(unsigned int)*capacity);
    memset(plist->pnode, 0, sizeof(unsigned int)*capacity);
    if(NULL == plist->pnode)
    {
        perror("SeqList_Create pnode");
        return NULL;
    }
    //plist->length = 0;
    plist->capacity = capacity;

    return plist;
}

//销毁一个线性表
void SeqList_Destroy(SeqList* plist)
{
    TSeqList *ptlist = (TSeqList*)plist;
    if(NULL == ptlist)
    {
        printf("SeqList is empty(SeqList_Destroy)!\n ");
        return ;
    }

    if(ptlist->pnode != NULL)
    {
        free(ptlist->pnode);
    }
    free(plist);
    return ;
}

//将一个线性表list中的所有元素清空,线性表回到创建时的状态
void SeqList_Clear(SeqList* plist)
{
    TSeqList *ptlist = (TSeqList*)plist;
    if(NULL == ptlist)
    {
        printf("SeqList is empty(SeqList_Clear)!\n ");
        return ;
    }
    ptlist->length = 0;
    return ;
}

//返回一个线性表list中的所有元素个数
int SeqList_Length(SeqList* plist)
{
    TSeqList *ptlist = (TSeqList*)plist;
    if(NULL == ptlist)
    {
        printf("SeqList is empty(SeqList_Length)!\n ");
        return -1;
    }

    return ptlist->length;
}

//向一个线性表list的pos位置处插入新元素node节点
int SeqList_Insert(SeqList* plist, SeqListNode* pnode, int pos)
{
    TSeqList *ptlist = (TSeqList*)plist;
    if(NULL == ptlist || NULL == pnode )
    {
        printf("SeqList is empty(SeqList_Insert)!\n ");
        return -1;
    }

    if( pos<-1 || pos >= ptlist->capacity )
    {
        printf("pos is unvalid(SeqList_Insert)!\n");
        return -2;
    }       

    int i;
    for(i=ptlist->length; i>pos; i--)
        ptlist->pnode[i] = ptlist->pnode[i-1];

    ptlist->pnode[pos] = (unsigned int*)pnode;
    ptlist->length ++;

    return 0;
}

//获取一个线性表list的pos位置处的元素
SeqListNode* SeqList_Get(SeqList* plist, int pos)
{
    TSeqList *ptlist = (TSeqList*)plist;
    if(NULL == ptlist)
    {
        printf("SeqList is empty(SeqList_Get)!\n ");
        return NULL;
    }

    if( pos<-1 || pos > ptlist->capacity )
    {
        printf("pos is unvalid(SeqList_Insert)!\n");
        return NULL;
    }       
    return ptlist->pnode[pos];
}

//删除一个线性表list的pos位的node节点元素,返回值为被删除的元素,NULL表示删除失败
SeqListNode* SeqList_Delete(SeqList* plist, int pos)
{
    TSeqList *ptlist = (TSeqList*)plist;
    if(NULL == ptlist)
    {
        printf("SeqList is empty!(SeqList_Delete)\n ");
        return NULL;
    }

    if( pos<-1 || pos > ptlist->capacity )
    {
        printf("pos is unvalid!(SeqList_Delete)\n");
        return NULL;
    }       

    SeqListNode *pnode = NULL;
    pnode = (SeqListNode*)ptlist->pnode[pos];

    int i;
    for(i=pos; i < ptlist->length; i++)
        ptlist->pnode[i] = ptlist->pnode[i+1];
    ptlist->length --;

    return pnode;
}

效果函数完结

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "seqlist.h"

//创建并且返回一个空的线性表
SeqList *SeqList_Create(int capacity)
{
    TSeqList *plist = NULL;

    plist = (TSeqList*)malloc(sizeof(TSeqList));
    memset(plist, 0, sizeof(TSeqList));
    if(NULL == plist)
    {
        perror("SeqList_Create TSeqList");
        return NULL;
    }
    plist->pnode = (unsigned int**)malloc(sizeof(unsigned int)*capacity);
    memset(plist->pnode, 0, sizeof(unsigned int)*capacity);
    if(NULL == plist->pnode)
    {
        perror("SeqList_Create pnode");
        return NULL;
    }
    //plist->length = 0;
    plist->capacity = capacity;

    return plist;
}

//销毁一个线性表
void SeqList_Destroy(SeqList* plist)
{
    TSeqList *ptlist = (TSeqList*)plist;
    if(NULL == ptlist)
    {
        printf("SeqList is empty(SeqList_Destroy)!\n ");
        return ;
    }

    if(ptlist->pnode != NULL)
    {
        free(ptlist->pnode);
    }
    free(plist);
    return ;
}

//将一个线性表list中的所有元素清空,线性表回到创建时的状态
void SeqList_Clear(SeqList* plist)
{
    TSeqList *ptlist = (TSeqList*)plist;
    if(NULL == ptlist)
    {
        printf("SeqList is empty(SeqList_Clear)!\n ");
        return ;
    }
    ptlist->length = 0;
    return ;
}

//返回一个线性表list中的所有元素个数
int SeqList_Length(SeqList* plist)
{
    TSeqList *ptlist = (TSeqList*)plist;
    if(NULL == ptlist)
    {
        printf("SeqList is empty(SeqList_Length)!\n ");
        return -1;
    }

    return ptlist->length;
}

//向一个线性表list的pos位置处插入新元素node节点
int SeqList_Insert(SeqList* plist, SeqListNode* pnode, int pos)
{
    TSeqList *ptlist = (TSeqList*)plist;
    if(NULL == ptlist || NULL == pnode )
    {
        printf("SeqList is empty(SeqList_Insert)!\n ");
        return -1;
    }

    if( pos<-1 || pos >= ptlist->capacity )
    {
        printf("pos is unvalid(SeqList_Insert)!\n");
        return -2;
    }       

    int i;
    for(i=ptlist->length; i>pos; i--)
        ptlist->pnode[i] = ptlist->pnode[i-1];

    ptlist->pnode[pos] = (unsigned int*)pnode;
    ptlist->length ++;

    return 0;
}

//获取一个线性表list的pos位置处的元素
SeqListNode* SeqList_Get(SeqList* plist, int pos)
{
    TSeqList *ptlist = (TSeqList*)plist;
    if(NULL == ptlist)
    {
        printf("SeqList is empty(SeqList_Get)!\n ");
        return NULL;
    }

    if( pos<-1 || pos > ptlist->capacity )
    {
        printf("pos is unvalid(SeqList_Insert)!\n");
        return NULL;
    }       
    return ptlist->pnode[pos];
}

//删除一个线性表list的pos位的node节点元素,返回值为被删除的元素,NULL表示删除失败
SeqListNode* SeqList_Delete(SeqList* plist, int pos)
{
    TSeqList *ptlist = (TSeqList*)plist;
    if(NULL == ptlist)
    {
        printf("SeqList is empty!(SeqList_Delete)\n ");
        return NULL;
    }

    if( pos<-1 || pos > ptlist->capacity )
    {
        printf("pos is unvalid!(SeqList_Delete)\n");
        return NULL;
    }       

    SeqListNode *pnode = NULL;
    pnode = (SeqListNode*)ptlist->pnode[pos];

    int i;
    for(i=pos; i < ptlist->length; i++)
        ptlist->pnode[i] = ptlist->pnode[i+1];
    ptlist->length --;

    return pnode;
}

逐一表简介

顺序表就是以数组的情势来存款和储蓄和治本事务节点。具体的数据结构如下图:

澳门永利备用网址 1

由上海教室能够,seqlist结构体就是实际的顺序表数据结构,length变量表示存款和储蓄的工作节点的个数,capacity变量表示pnode指向的堆区空间容积。该堆区是二个指南针数组,每二个数组成分存款和储蓄三个业务节点的地点,来针对各样业务节点,由此,管理这几个指针数组的是三个二级指针pnode;

次第表简介

顺序表正是以数组的款式来囤积和保管工作节点。具体的数据结构如下图:

澳门永利备用网址 2

由上海体育场所可以,seqlist结构体正是具体的顺序表数据结构,length变量表示存储的事务节点的个数,capacity变量表示pnode指向的堆区空间容积。该堆区是3个指针数组,每2个数组元素存款和储蓄贰个作业节点的地址,来针对种种业务节点,由此,管理那个指针数组的是四个二级指针pnode;

澳门永利备用网址,总结

学数据结构大家要做的不光是读书数据结构的算法完成,更要紧的是能写出一种具有普适性的工具,站在1个更高的统一筹划策略的角度去设计代码,这一点对于学习数据结构来说很主要,没有那一点做支撑,学到的数据结构就只是二个空壳子,无法灵活的施用。

头文件表明

//seqlist.h
#ifndef _SEQLIST_H_
#define _SEQLIST_H_

typedef void SeqList;
typedef void SeqListNode;

typedef struct tag_SeqList{
    int length;
    int capacity;
    unsigned int **pnode;
}TSeqList;

//创建并且返回一个空的线性表
SeqList *SeqList_Create(int capacity);

//销毁一个线性表
void SeqList_Destroy(SeqList* plist);

//将一个线性表list中的所有元素清空,线性表回到创建时的状态
void SeqList_Clear(SeqList* plist);

//返回一个线性表list中的所有元素个数
int SeqList_Length(SeqList* plist);

//向一个线性表list的pos位置处插入新元素node节点
int SeqList_Insert(SeqList* plist, SeqListNode* pnode, int pos);

//获取一个线性表list的pos位置处的元素
SeqListNode* SeqList_Get(SeqList* plist, int pos);

//删除一个线性表list的pos位的node节点元素,返回值为被删除的元素,NULL表示删除失败
SeqListNode* SeqList_Delete(SeqList* plist, int pos);

//遍历顺序表
#define SeqList_Traverse(plist,node_type,number) \
({ \
    int i;\
    for(i=0; i < plist->length; i++) { \
        printf("number: %d\n",((typeof(node_type)*)(plist->pnode[i]))->number);\
    }  })
#endif //seqlist.h

seqlist.h头文件是对顺序表数据结构和意义接口的画饼充饥。在那当中,重要注意一下几点:

  • SeqList和SeqListNode的数据类型:
    是将void数据类型的包装。原因之一是增长代码的可读性,其二,将void封装,是为了合作更六种类型的工作节点。
  • 以宏函数方式遍历顺序表:先是,小编想说名的少数是,遍历的效益实在在大家规划数据结构的操作函数时是没要求设计的。我们统一筹划的是对业务节点的军管,是“增加和删除改查”,“查”本就能够取得想要的工作节点,但当自家设计是,大家平常会波及遍历的功效,可在本身陈设时意识,数组指针中数组成分指向的事务节点的数据类型不明确,所以不能用printf函数直接打字与印刷想要的节点数据。想尝尝的化解这几个标题,于是本人才设计了那几个宏函数。不用定义的函数的艺术去实现遍历功用,是因为不能够在形参中央直机关接获得工作节点的数据类型,只可以通过宏的款型得到工作节点的数据类型。测试代码如下:

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

typedef struct a{
    char ch;
    int num;
}A; 
int main ()
{
    A a;
    void *ptype = NULL;
    ptype = (void *)&a;
    printf("%lu\n",sizeof(typeof(ptype)));
    return 0;
}

运维的结果是:4,而不是8。获得的是ptype指针的数据类型,而不是struct
a那种数据类型。倘使我们用定义函数的情势而不是概念宏函数的方法去落到实处遍历时,那么,大家接受工作节点的形参只好是“void
*”类型,但大家鞭长莫及在函数内部使用typeof关键子获取到形参指向的数目标数据类型,而宏函数能到位。

头文件申明

//seqlist.h
#ifndef _SEQLIST_H_
#define _SEQLIST_H_

typedef void SeqList;
typedef void SeqListNode;

typedef struct tag_SeqList{
    int length;
    int capacity;
    unsigned int **pnode;
}TSeqList;

//创建并且返回一个空的线性表
SeqList *SeqList_Create(int capacity);

//销毁一个线性表
void SeqList_Destroy(SeqList* plist);

//将一个线性表list中的所有元素清空,线性表回到创建时的状态
void SeqList_Clear(SeqList* plist);

//返回一个线性表list中的所有元素个数
int SeqList_Length(SeqList* plist);

//向一个线性表list的pos位置处插入新元素node节点
int SeqList_Insert(SeqList* plist, SeqListNode* pnode, int pos);

//获取一个线性表list的pos位置处的元素
SeqListNode* SeqList_Get(SeqList* plist, int pos);

//删除一个线性表list的pos位的node节点元素,返回值为被删除的元素,NULL表示删除失败
SeqListNode* SeqList_Delete(SeqList* plist, int pos);

//遍历顺序表
#define SeqList_Traverse(plist,node_type,number) \
({ \
    int i;\
    for(i=0; i < plist->length; i++) { \
        printf("number: %d\n",((typeof(node_type)*)(plist->pnode[i]))->number);\
    }  })
#endif //seqlist.h

seqlist.h头文件是对顺序表数据结构和效应接口的空洞。在那中间,主要注意一下几点:

  • SeqList和SeqListNode的数据类型:
    是将void数据类型的包装。原因之一是提升代码的可读性,其二,将void封装,是为了同盟更各体系型的业务节点。
  • 以宏函数形式遍历顺序表:第1,作者想说名的一些是,遍历的功力实在在我们设计数据结构的操作函数时是没必要设计的。我们计划的是对作业节点的管理,是“增加和删除改查”,“查”本就足以博得想要的事务节点,但当自身安排是,大家常常会涉及遍历的意义,可在自作者设计时意识,数组指针中数组成分指向的政工节点的数据类型不鲜明,所以不能够用printf函数直接打字与印刷想要的节点数据。想尝试的化解那么些标题,于是本身才设计了这么些宏函数。不用定义的函数的办法去贯彻遍历作用,是因为不恐怕在形参中直接获得工作节点的数据类型,只可以通过宏的样式取得工作节点的数据类型。测试代码如下:

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

typedef struct a{
    char ch;
    int num;
}A; 
int main ()
{
    A a;
    void *ptype = NULL;
    ptype = (void *)&a;
    printf("%lu\n",sizeof(typeof(ptype)));
    return 0;
}

运作的结果是:4,而不是8。获得的是ptype指针的数据类型,而不是struct
a这种数据类型。借使我们用定义函数的主意而不是概念宏函数的法门去落到实处遍历时,那么,大家收起工作节点的形参只好是“void
*”类型,但大家鞭长莫及在函数内部选取typeof关键子获取到形参指向的多少的数据类型,而宏函数能成功。

总结

学数据结构大家要做的不不过读书数据结构的算法达成,更主要的是能写出一种具有普适性的工具,站在1个更高的安排性策略的角度去规划代码,那点对于学习数据结构来说很关键,没有那一点做支撑,学到的数据结构就只是一个空壳子,非常小概灵活的施用。

功能测试代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "seqlist.h"

typedef struct student{
    char name[20];
    int age;
}student;

int main(int argc, char *argv[])
{
    student stu1,stu2,stu3,stu4,stu5;

    stu1.age = 20;
    stu2.age = 21;
    stu3.age = 22;
    stu4.age = 23;
    stu5.age = 24;

   TSeqList *pslist = (TSeqList*)SeqList_Create(5);

    SeqList_Insert(pslist, (SeqListNode*)&stu1, 0);
    SeqList_Insert(pslist, (SeqListNode*)&stu2, 1);
    SeqList_Insert(pslist, (SeqListNode*)&stu3, 2);
    SeqList_Insert(pslist, (SeqListNode*)&stu4, 3);
    SeqList_Insert(pslist, (SeqListNode*)&stu5, 4);
    printf("length: %d\n",SeqList_Length(pslist));
    SeqList_Traverse(pslist,student,age);

    SeqList_Delete(pslist,2);
    printf("length: %d\n",SeqList_Length(pslist));
    int i;
    student *ptmp = NULL;
    for(i=0; i < SeqList_Length(pslist); i++)
    {   
        ptmp = SeqList_Get(pslist,i);   
        printf("age: %d\n",ptmp->age);
    }
    SeqList_Clear(pslist);
    SeqList_Destroy(pslist);
    return 0;
}