数据结构中线性表的顺序存储及其操作
在数据结构的学习中我们能够知道线性表的存储方式分为两种存储方式,有链式存储,与此同时呢,我们还有一种顺序存储方式,下面就是线性表的顺序存储的结构体以及此存储方式下的各种操作:
- 存储结构体
- 初始化线性表
- 销毁线性表
- 清空线性表
- 线性表的数据插入
- 查找线性表中的元素
- 删除表中的某个元素
- 线性表的合并
- 遍历线性表
首先线性表要存储就得有个存储的结构体:
typedef struct Sqlist{
ElemType *Elem_array;//指针结构存储线性表里的元素
int length;//表示线性表的长度
}SqList;
初始化线性表就是为一个还没有空间的数组向系统申请空间,具体代码如下:
Status InitList_Sq(SqList *L)
{
L->Elem_array = (ElemType * )malloc(MAX_SIZE*sizeof(ElemType));//向系统申请空间
if(!L->Elem_array)
return ERROR; //申请失败则返回error
else{ //否则就申请成功
L->length = 0;//将长度置为0,返回ok
return OK;
}
}
销毁线性表则是将已有的数组占有的空间返还给系统
Status DestoryList_Sq(SqList *L)
{
free(L);
L->Elem_array= NULL;
L->length = 0;
return OK;
}
然而清空线性表则是将线性表中的元素全部清空,并不用将空间返还给系统,因此就这样写代码了
Status ClearList_Sq(SqList *L)
{
L->Elem_array = NULL;
L->length = 0;
return OK;
}
插入元素时需要传递一个位置,还需要一个元素值和向那个插入元素的线性表,例如插入值为5,插入的位置是3,过程如图所示:
插入代码如下:
Status Insert_SqList(SqList *L, int i, ElemType e)
{
if(i < 0 || i > MAX_SIZE)
return ERROR; //此处判断传递过来的位置是否越界,若是越界则返回错误
if(L->length > MAX_SIZE)
{
printf("线性表溢出\n");//判断线性表的长度是否超过了最长长度
return ERROR;
}
int j;
for(j = MAX_SIZE-1; j > i-2; --j)
{
L->Elem_array[j+1] = L->Elem_array[j];//将第i个位置后的元素统统往后移动一位
}
L->Elem_array[i-1] = e;//将需要插入的元素值插入到线性表中
L->length++;
return OK;
}
在线性表中查找元素,将整个线性表挨个遍历一遍,如果找到该元素,则返回此元素在线性表中的位置,代码如下:
ElemType Select_SqList(SqList *L, int i)
{
ElemType x;
int k;
for(k = 0; k < L->length; k++)//循环遍历线性表进行查找
{
if(L->Elem_array[k] == i)
{
x = k+1;//计算位置
break;
}
}
return x;
}
删除线性表中的元素和插入元素类似,我们只需要将要删除的元素记下,然后将该元素后面的每个元素统统往前移动即可,代码就可以这样写
Status Delete_SqList(SqList *L, int i)
{
int k;
if(L->length==0)//首先判断线性表是否为空
{
printf("线性表的长度为空\n");
return ERROR;
}
if(i < 1 || i > L->length)//判断传递过来的位置是否合法
{
printf("您要删除的元素不存在\n");
return ERROR;
}
else
{
ElemType x;
x = L->Elem_array[i - 1];
for(k = i; k < L->length; k++)
{
L->Elem_array[k - 1] = L->Elem_array[k];
}
L->length--;
printf("已删除!\n");
return x;
}
}
将两个有序的线性表合并为一个线性表使之仍然有序,此函数利用的是排序算法中的归并排序算法,归并算法是适用于排序中,但是此处我们也是可以用的,因为将两个有序的表合并,也就相当于是一个归并过程,示意图如下
合并线性表的代码如下:
void LinkList(SqList *L1, SqList *L2)
{
SqList L3;//定义一个新的线性表
InitList_Sq(&L3);//进行初始化
if(L1->length == 0)//如果第一个表是空表则直接将第二个表赋值给新的表就可以
{
L3.length = L2->length;
int i;
for(i = 0; i < L2->length; i++)
{
L3.Elem_array[i] = L2->Elem_array[i];
}
}
else if(L2->length==0)//同理可知第二个表为空表的情况
{
L3.length = L1->length;
int i;
for(i = 0; i < L1->length; i++)
{
L3.Elem_array[i] = L1->Elem_array[i];
}
}
else if(L1->length != 0 && L2->length != 0)//归并开始
{
int i, j, k;
i = j = 0;
k = 0;
while((i < L1->length) && (j < L2->length))//两个表当前位置小于整个表的长度时
{
if(L1->Elem_array[i] <= L2->Elem_array[j])//如果表1当前的值小于表2当前的值
{
Insert_SqList(&L3, ++k, L1->Elem_array[i]);//调用上述的插入函数进行插入
++i;
}else{
Insert_SqList(&L3, ++k, L2->Elem_array[j]);//同理
++j;
}
}
while(i < L1->length)//将循环完实现完后表1剩余的元素插入到新表中
{
Insert_SqList(&L3, ++k, L1->Elem_array[i]);
i++;
}
while(j < L2->length)//将循环完实现完后表2剩余的元素插入到新表中
{
Insert_SqList(&L3, ++k, L2->Elem_array[j]);
j++;
}
}
printf("合并后的线性表:\n");
ListTraverse(&L3);//遍历新的线性表
}
整个程序的完整算法代码如下所示:
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
#define LISTINCREMENT 10
#define OK 1
#define ERROR -1
typedef int Status;
typedef int ElemType;
typedef struct Sqlist{
ElemType *Elem_array;
int length;
//int listsize;
}SqList;
Status InitList_Sq(SqList *L);//初始化线性表
Status DestoryList_Sq(SqList *L);//销毁线性表
Status ClearList_Sq(SqList *L);//清空线性表
Status Insert_SqList(SqList *L, int i, ElemType e);//线性表的数据插入操作
ElemType Select_SqList(SqList *L, int i);//线性表查找
Status Delete_SqList(SqList *L, int i);//删除线性表的某个元素
void LinkList(SqList *L1, SqList *L2);//合并两个有序的线性表
void Bubble_Sort(SqList *L);//将线性表进行排序
void ListTraverse(SqList *L);//遍历线性表
int main()
{
struct Sqlist Sqlist;//定义一个Sqlist的结构体
SqList Sq1;//结构体2
int res, ques, resq;//res表示函数返回值 ques表示要查找的数 resq表示需要删除的数的位置
int local;//需要插入数的位置
int elem;//需要插入的数
res = InitList_Sq(&Sqlist);
if(res == 1){
printf("线性表已初始化!\n");
}else{
printf("线性表初始化失败!\n");
}
Sqlist.length = 5;
printf("请给你的线性表1赋初始值:");
int k;
for(k = 0; k < Sqlist.length; k++)
{
scanf("%d", &Sqlist.Elem_array[k]);
}
res = InitList_Sq(&Sq1);
if(res == 1){
printf("线性表已初始化!\n");
}else{
printf("线性表初始化失败!\n");
}
Sq1.length = 4;
printf("请给你的线性表2赋初始值:");
int j;
for(j = 0; j < Sq1.length; j++)
{
scanf("%d", &Sq1.Elem_array[j]);
}
Bubble_Sort(&Sqlist);
Bubble_Sort(&Sq1);
printf("线性表1:");
ListTraverse(&Sqlist);
printf("线性表2:");
ListTraverse(&Sq1);
printf("提示:以下操作均为对线性表1的处理!\n");
printf("请输入你需要添加数的位置:");
scanf("%d", &local);
printf("请输入你需要添加的元素:");
scanf("%d", &elem);
res = Insert_SqList(&Sqlist, local, elem);
printf("插入线性表1后为:\n");
ListTraverse(&Sqlist);
printf("请输入你想要查找的数:");
scanf("%d", &ques);
res = Select_SqList(&Sqlist, ques);
printf("你查找的数在第%d个位置上\n", res);
printf("请输入你想要删除的数的序号:");
scanf("%d", &resq);
res = Delete_SqList(&Sqlist, resq);
printf("删除后的线性表为:\n");
ListTraverse(&Sqlist);
//res = ClearList_Sq(&Sqlist);
//printf("%d\n", res);
printf("连接两个有序的线性表:");
LinkList(&Sq1, &Sqlist);
return 0;
}
//初始化数组
Status InitList_Sq(SqList *L)
{
L->Elem_array = (ElemType * )malloc(MAX_SIZE*sizeof(ElemType));
if(!L->Elem_array)
return ERROR;
else{
L->length = 0;
return OK;
}
}
//销毁线性表
Status DestoryList_Sq(SqList *L)
{
free(L);
L->Elem_array= NULL;
L->length = 0;
return OK;
}
//将线性表重置为空表
Status ClearList_Sq(SqList *L)
{
L->Elem_array = NULL;
L->length = 0;
return OK;
}
//插入数据到第i个位置
Status Insert_SqList(SqList *L, int i, ElemType e)
{
if(i < 0 || i > MAX_SIZE)
return ERROR;
if(L->length > MAX_SIZE)
{
printf("线性表溢出\n");
return ERROR;
}
int j;
for(j = MAX_SIZE-1; j > i-2; --j)
{
L->Elem_array[j+1] = L->Elem_array[j];
}
L->Elem_array[i-1] = e;
L->length++;
return OK;
}
//根据元素名称进行查找
ElemType Select_SqList(SqList *L, int i)
{
ElemType x;
int k;
for(k = 0; k < L->length; k++)
{
if(L->Elem_array[k] == i)
{
x = k+1;
break;
}
}
return x;
}
//根据序号来删除
Status Delete_SqList(SqList *L, int i)
{
int k;
if(L->length==0)
{
printf("线性表的长度为空\n");
return ERROR;
}
if(i < 1 || i > L->length)
{
printf("您要删除的元素不存在\n");
return ERROR;
}
else
{
ElemType x;
x = L->Elem_array[i - 1];
for(k = i; k < L->length; k++)
{
L->Elem_array[k - 1] = L->Elem_array[k];
}
L->length--;
printf("已删除!\n");
return x;
}
}
//连接两个线性表合为一个线性表
void LinkList(SqList *L1, SqList *L2)
{
SqList L3;
InitList_Sq(&L3);
if(L1->length == 0)
{
L3.length = L2->length;
int i;
for(i = 0; i < L2->length; i++)
{
L3.Elem_array[i] = L2->Elem_array[i];
}
}
else if(L2->length==0)
{
L3.length = L1->length;
int i;
for(i = 0; i < L1->length; i++)
{
L3.Elem_array[i] = L1->Elem_array[i];
}
}
else if(L1->length != 0 && L2->length != 0)
{
int i, j, k;
i = j = 0;
k = 0;
while((i < L1->length) && (j < L2->length))
{
if(L1->Elem_array[i] <= L2->Elem_array[j])
{
Insert_SqList(&L3, ++k, L1->Elem_array[i]);
++i;
}else{
Insert_SqList(&L3, ++k, L2->Elem_array[j]);
++j;
}
}
while(i < L1->length)
{
Insert_SqList(&L3, ++k, L1->Elem_array[i]);
i++;
}
while(j < L2->length)
{
Insert_SqList(&L3, ++k, L2->Elem_array[j]);
j++;
}
}
printf("合并后的线性表:\n");
ListTraverse(&L3);
}
//将无序的线性表按从小到大排序
void Bubble_Sort(SqList *L)
{
int j;
int k;
for(j = 0; j < L->length; j++)
{
for(k = 0; k < L->length - j - 1; k++)
{
if(L->Elem_array[k] > L->Elem_array[k+1])
{
ElemType temp;
temp = L->Elem_array[k];
L->Elem_array[k] = L->Elem_array[k+1];
L->Elem_array[k+1] = temp;
}
}
}
}
//遍历整个数组输出到屏幕上
void ListTraverse(SqList *L)
{
if(L->Elem_array == NULL)
{
printf("该数组为空!");
}
else
{
int k;
for(k = 0; k < L->length; k++)
{
printf("%4d", L->Elem_array[k]);
}
printf("\n");
}
}
程序运行示例如下: