线性表的顺序存储结构的表示和实现
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;
}
注意:顺序表的操作可以不用传指针,其实也没必要。