线性表的顺序存储结构的表示和实现

线性表的顺序存储结构的表示和实现
1、线性表定义:零个或多个数据元素的有限序列
首先,它是一个序列。也就是说,元素之间是有顺序的,若元素存在多个,则第一个元素无前驱,最后一个元素无后继,其他每个元素有且只有一个前驱和一个后继。然后,线性表强调是有限的,说的是元素个数是有限的。
2、线性表元素的个数n(n≥0)定义为线性表的长度,当n=0时,称为空表。
3、线性表的顺序存储结构:指的是用一段地址连续的存储单元依次存储线性表的数据元素。用一维数组来实现顺序存储结构。存储器中的每个单元都有自己的编号,这个编号成为地址。
4、优点:无需为表示表中元素之间的逻辑关系而增加额外的存储空间;可以快速的存取表中任一位置的元素。
缺点:插入和删除操作需要移动大量元素;当线性表长度比较大时,难以确定存储空间的容量;造成存储空间的“碎片”。
线性表的顺序存储结构的表示和实现如下:

1、定长顺序表

(1)"mylist.h"

#ifndef MYLIST
#define MYLIST

typedef int elem_type;
#define MAXSIZE 20
#include 
#include 

typedef struct
{
    elem_type elems[MAXSIZE];
    int len;
}list;

void init_l(list *l);
int getIndexByElem(list *l,elem_type e);
void getValByIndex(list *l,int index,elem_type *value);
int insert_l(list *l,int pos,int value);
int delete_value(list *l,elem_type e);
void print_l(list *l);

#endif

(2)"list.cpp"

#include "mylist.h"

void init_l(list *l)
{
    assert(NULL != l);
    int i;
    for(i = 0;i < MAXSIZE;++i)
    {
        l->elems[i] = 0;
    }
    l->len = 0;
}

int getIndexByElem(list *l,elem_type e)
{
    assert(NULL != l);
    int i = 0;
    for(i = 0;i < l->len;++i)
    {
        if (e == l->elems[i])
        {
            return i;
        }
    }
    return -1;
}

void getValByIndex(list *l,int index,elem_type *value)
{
    assert(NULL != l);
    *value = l->elems[index];
}

int insert_l(list *l,int pos,int value)
{
    assert(NULL != l);
    if (pos<0 || pos > l->len || l->len >= MAXSIZE )
    {
        return 0;
    }
    else
    {
        int i;
        for(i = MAXSIZE-1;i > pos;i--)
        {
            l->elems[i] = l->elems[i-1];
        }
        l->elems[pos] = value;
        l->len++;
        return 1;
    }
}

int delete_value(list *l,elem_type e)
{
    assert(NULL != l);
    for (int i=0; ilen; ++i)
    {
        if (l->elems[i] == e)
        {
            for (int j=i; jlen; ++j)
            {
                l->elems[j] = l->elems[j+1];
            }
            l->elems[len-1] = 0;
            l->len--;
            return 1;
        }
    }
    return 0;
}

void print_l(list *l)
{
    assert(NULL != l);
    for (int i=0; ilen; ++i)
    {
        printf("%d ",l->elems[i]);
    }
    printf("\n");
}

(3)"test_list.cpp"

#include "mylist.h"

int main()
{
    list l; 
    init_l(&l);
    print_l(&l);

    int i;
    for (i = 0;i<5;++i)
    {
        insert_l(&l,i,i+1);
    }
    print_l(&l);

    insert_l(&l,3,10);
    printf("len = %d\n",l.len);
    print_l(&l);

    int val;
    getValByIndex(&l,4,&val);
    printf("val = %d\n",val);

    int index = getIndexByElem(&l,2);
    printf("index = %d\n",index);

    delete_value(&l,4);
    print_l(&l);

    return 0;
}

2、不定长顺序表

(1)"dsqlist.h"

#ifndef DSQLIST
#define DSQLIST

typedef int ELEM_TYPE;
#define INCREMENT 10    //扩容每次增加10
#define INIT_SIZE 10    //初始化长度

typedef struct  
{
    ELEM_TYPE *elem;
    int length;
    int total_size;
}dsqlist;

void init_dsqlist(dsqlist *plist);
void destroy_dsqlist(dsqlist *plist);
bool insert(dsqlist *plist,int pos,ELEM_TYPE val);
bool is_empty(dsqlist *plist);
bool is_full(dsqlist *plist);
void inc(dsqlist *plist);
void clear(dsqlist *plist);

int get_length(dsqlist *plist);
bool delete_value(dsqlist *plist, ELEM_TYPE val);
bool delete_pos(dsqlist *plist, int pos);
int search(dsqlist *plist, ELEM_TYPE key);
void show(dsqlist *plist);
bool get_elem(dsqlist *plist, int pos, ELEM_TYPE *e);
void insert_dsqlist_sort(dsqlist *plist,ELEM_TYPE x);
void reverse_dsqlist(dsqlist *plist);
#endif

(2)"dsqlist.cpp"

#include "dsqlist.h"
#include 
#include 
#include 
#include 

void init_dsqlist(dsqlist *plist)
{
    assert(NULL != plist);
//  plist->elem = (ELEM_TYPE *)calloc(INIT_SIZE,sizeof(int));
    plist->elem = (ELEM_TYPE *)malloc(sizeof(int)*INIT_SIZE);
    assert(NULL != plist->elem);
    memset(plist->elem,0,INIT_SIZE*sizeof(int));
    plist->length = 0;
    plist->total_size = INIT_SIZE;
}

void destroy_dsqlist(dsqlist *plist)
{
    assert(NULL != plist);
    free(plist->elem);
    plist->elem = NULL;
    plist->length = 0;
    plist->total_size = 0;
}

bool is_empty(dsqlist *plist)
{
    assert(NULL != plist);
    return plist->length == 0;
}

bool is_full(dsqlist *plist)
{
    assert(NULL != plist);
    return plist->length == plist->total_size;
}

//扩增容量
void inc(dsqlist *plist)
{
    assert(NULL != plist);
    plist->elem = (ELEM_TYPE *)realloc(plist->elem,(plist->total_size+INCREMENT)*sizeof(int));
    assert(NULL != plist->elem);
    plist->total_size += INCREMENT; 
}

//向指定位置插入元素
bool insert(dsqlist *plist,int pos,ELEM_TYPE val)
{
    assert(NULL != plist);
    if (pos < 0 || pos > plist->length)//非法位置
    {
        printf("插入位置错误\n");
        return false;
    }

    if (is_full(plist))
    {
    /*  ELEM_TYPE *temp = plist->elem;
        ELEM_TYPE *new_elem = (ELEM_TYPE *) calloc(plist->total_size+INCREMENT,sizeof(int));
        if (NULL != new_elem)
        {
            plist->elem = new_elem;
            int i;
            for (i=0; ilength; ++i)
            {
                plist->elem[i] = temp[i];
            }
            plist->total_size += INCREMENT;
        }
        else
        {
            return false;
        }
        */
        inc(plist);
    }

    int i;
    for (i=plist->length; i>pos; --i)
    {
        plist->elem[i] = plist->elem[i-1];
    }
    plist->elem[pos] = val;
    plist->length++;
}

void clear(dsqlist *plist)
{
    assert(NULL != plist);
    if (!is_empty(plist))
    {
        int i;
        for (i=0; ilength; ++i)
        {
            plist->elem[i] = 0;
        }
        plist->length = 0;
        plist->total_size = INIT_SIZE;
    }
    printf("清空成功,请重新添加元素\n");
}

int get_length(dsqlist *plist)
{
    assert(NULL != plist);
    return plist->length;
}

//根据值删除
bool delete_value(dsqlist *plist, ELEM_TYPE val)
{
    assert(NULL != plist);
    int i,j;
    bool flag = false;
    if (!is_empty(plist))
    {
        for (i=0; ilength; ++i)
        {
            if (val == plist->elem[i])
            {
                for (j=i; jlength-1; ++j)
                {
                    plist->elem[j] = plist->elem[j+1];
                }
                plist->elem[plist->length-1] = 0;
                flag = true;
                plist->length--;
                break;
            }
        }
    }

    return flag;
}

//根据坐标删除
bool delete_pos(dsqlist *plist, int pos)
{
    assert(NULL != plist);
    if (pos < 0 || pos > plist->length-1)
    {
        return 0;
    }

    int i;
    for (i=pos; ilength-1; ++i)
    {
        plist->elem[i] = plist->elem[i+1]; 
    }
    plist->elem[plist->length-1] = 0;
    plist->length--;

    return 1;
}
//根据值找下标
int search(dsqlist *plist, ELEM_TYPE key)
{
    assert(NULL != plist);
    int pos = -1;
    int i;
    for (i=0;ilength;++i)
    {
        if(key == plist->elem[i])
        {
            pos = i;
        }
    }

    return pos;
}

void show(dsqlist *plist)
{
    assert(NULL != plist);
    int i;
    if (is_empty(plist))
    {
        printf("当前没有数据\n");
        return;
    }

    for (i=0;ilength;++i)
    {
        if (i != plist->length-1)
        {
            printf("%d,",plist->elem[i]);
        }
        else
        {
            printf("%d\n",plist->elem[i]);
        }
    }
}

//查找指定下标的值
bool get_elem(dsqlist *plist, int pos, ELEM_TYPE *e)
{
    assert(NULL != plist);
    if (pos < 0 || pos > plist->length-1)
    {
        return 0;
    }
    *e = plist->elem[pos];

    return 1;
}

//插入有序顺序表中
void insert_dsqlist_sort(dsqlist *plist,ELEM_TYPE x)
{
    int i,j;
    if(is_full(plist))
    {
        inc(plist);
    }

    int len = plist->length;
    if (x > plist->elem[len-1])
    {
        plist->elem[len] = x;
        plist->length++;
        return;
    }

    for(i=0; iif(plist->elem[i] >= x)
        {
            //元素后移
            for(j=plist->length; j>i; --j)
            {
                plist->elem[j] = plist->elem[j-1];
            }
            plist->elem[i] = x;
            plist->length++;
            break;
        }
    }

}

//逆置顺序表
void reverse_dsqlist(dsqlist *plist)
{
    int i;
    int n = plist->length/2;

    for(i=0; i//交换元素
        int temp = plist->elem[i];
        plist->elem[i] = plist->elem[plist->length-i-1];
        plist->elem[plist->length-i-1] = temp;
    }
}

(3)"test_dsqlist.cpp"

#include "dsqlist.h"
#include 

//初始化长度为10,扩容时每次增加10
int main()
{
    dsqlist dl;
    init_dsqlist(&dl);
    show(&dl);
    int i;
    for (i=0;i<5;++i)
    {
        insert(&dl,i,i+1);
    }
    show(&dl);

    insert_dsqlist_sort(&dl,8);
    insert_dsqlist_sort(&dl,6);
    show(&dl);

    printf("total_size = %d\n",dl.total_size);
    reverse_dsqlist(&dl);
    show(&dl);

    insert(&dl,5,15);
    insert(&dl,25,100);//插入位置错误
    show(&dl);

    if (delete_value(&dl,5))
    {
        printf("删除成功\n");
        show(&dl);
    }
    else
    {
        printf("删除失败\n");
        show(&dl);
    }

    int length = get_length(&dl);
    printf("length: %d\n",length);

    int val = 12;
    int pos = search(&dl,val);
    printf("要查找的元素%d在第%d个位置\n",val,pos);

    int e;
    int pos2 = 4;
    get_elem(&dl,pos2,&e);
    printf("第%d个位置的元素e = %d\n",pos2,e);

    clear(&dl);
    show(&dl);

    destroy_dsqlist(&dl);

    return 0;
}

注意:顺序表的操作可以不用传指针,其实也没必要。

你可能感兴趣的:(数据结构和算法)