最近开始学习数据结构与算法,一直认为数据结构与算法是值得一个程序员用一生去研究的东西,所以决定每次所学所得记录下来,加深自己的印象。
顺序表
什么是顺序表
我们知道在计算机中我们可以用不同的方法来存储数据,最常用的就是顺序存储,顺序存储指的是我们在计算机内存中用一块连续的地址内存空间按顺序存储线性表的各个数据元素。这就是顺序表。那么,我们立马能想到的一个顺序表是什么呢?没错,就是我们最常使用的数组。
为什么要学习顺序表
顺序表有许多优点,在使用数据的时候,我们可以用顺序表实现对数据的随机存取,由于这种使用数据的方便性,所以使得顺序表成为我们最常用使用的一种数据结构之一。
顺序表的数据结构
#define MAXSIZE <顺序表可能达到的最大长度>
typedef int ElemType;
typedef struct
{
ElemType elem[MAXSIZE+1];
int length; //线性表长度
}seqlist;
注意:由于数组的下标是由0开始的,我们通常为了方便使用,下标0基本是不存放数据的,因此下标的取值范围是 1~MAXSIZE-1。
顺序表的基本运算
顺序表的初始化
将顺序表的长度置为0即可。
void Init_Seqlist(Seqlist *L)
{
L -> length = 0;
}
顺序表的插入
和数组是一样的,具体的操作步骤如下:
1.先给新元素让出位置,为此要将插入位置i之后的元素从尾到头向下移动
2.将x插入到i位置
3.修改表长
int Insert_Seqlist(struct *L, int i, int x)
{
/*先要判断顺序表是否已满*/
if(L -> length == MAXSIZE -1)
{
return -1;
}
/*判断插入位置的正确性*/
if(1 <= i <= length)
{
/*将位置i以后的元素整体向后移动一个单位*/
for(j = length; j >= i; j--)
{
L -> elem[j+1] = L -> elem[j];
}
L -> elem[i] = x;
L -> length++;
}
return 0;
}
顺序表的删除
操作步骤:
1.将i位置之后的元素一次向上移动一个位置
2. 将length的值减一
int Delete_Seqlist(Seqlist *L, int i)
{
/*判断表非空*/
if(L -> length <= 0)
{
return -1;
}
/*将i后面的元素向上移动一个位置*/
for(j = i; j < length; j++)
{
L -> elem[j] = L -> length[j+1];
}
L -> length--;
return 0;
}
顺序表的按值查找
给定一个值x,在顺序表中查找第一个和x相等的数据元素,并返回它的位置。如没有与x相等的元素则返回-1。
int Location_Seqlist(Seqlist *L, int x)
{
for(int i = 1; i < length; i++)
{
if(L -> elem[i] != x)
{
i++;
}
else
{
return i;
}
}
if(i >= length)
{
return -1;
}
}
两个顺序表的合并
将A,B两个已经排好序的顺序表按升序合并为C,只需设置两个指针,分别指向A和B,每次将指针指向的两个元素进行比较,将较小的赋值给C,再将余下未处理的数据移植到C即可。
void merge(Seqlist *A, Seqlist *B, Seqlist *C)
{
int len; /*C表的长度*/
int i = 1, j = 1;
for(len = A -> length + B -> length; C -> length <= len; C -> length++)
{
/*将长度较长的表赋值给C*/
while(i > A -> length && j <= B -> length)
{
C -> elem[C -> length++] = B -> length;
j++;
}
while(i <= A -> length && j > B -> length)
{
C -> elem[C -> length++] = A -> length;
i++;
}
/*对两个指针所指向的元素进行比较并赋值给C*/
if(A -> elem[i] < B -> elem[j])
{
C -> elem[C -> length++] = A -> elem[i];
i++;
}
else
{
C -> elem[C -> length++] = B -> elem[j];
j++;
}
}
}
总结
总的来说,顺序表就是数组,只不过是将数组进行了抽象化,并进行了封装,两个数据结构的使用方式是没有什么基本的区别。当然,通过上面的代码我们可以看出,虽然顺序表继承了数组的对数据存取的方便性,但要对它进行数据的插入和删除,明显是没有链表容易与简单,这也算是线性表一个致命的缺陷。