今天,我们来学习第一种数据结构-线性表,什么是线性表呢?
线性表是数据结构的一种,是n个具有相同特性的数据元素的有限序列,表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。
它有四个特性
- 集合中必存在唯一的一个“第一元素”;
- 集合中必存在唯一的一个 “最后元素”;
- 除最后一个元素之外,均有 唯一的后继(后件);
- 除第一个元素之外,均有 唯一的前驱(前件);
它有这几个基本操作
- List_Init(SqListPtr L);//初始化线性表
- List_Destroy(SqListPtr L); //摧毁线性表
- List_Clear(SqListPtr L);//清空线性表
- List_Empty(SqListPtr L);//判断线性表是否为空
- List_Size(SqListPtr L);//求线性表的长度
- List_Retrival(SqListPtr L,int pos,ElemType * elem);//从线性表中提取pos位置的元素
- List_Locate(SqListPtr L,ElemType elem,int *pos);//将elem元素在线性表中的位置放在pos中
- List_Insert(SqListPtr L,int pos,ElemType elem);//添加元素
- List_delete(SqListPtr L,int pos);//删除元素
- List_Prior(SqListPtr L,int pos,ElemType * elem);//求elem的直接前序
- List_Next(SqListPtr L,int pos,ElemType * elem);//求elem的直接后继
- List_Print(SqListPtr L);//打印线性表
下面,我们看具体代码
//SqList.h
#pragma once
#define LIST_INIT_SIZE 100
#define LIST_INCREAMENT 10
enum Status{
success,fail,fatal,rang_error
};
typedef int ElemType;
typedef struct SqList
{
ElemType * elem;
int length;
int list_size;
}SqList,* Ptr,* SqListPtr;
Status List_Init(SqListPtr L);
void List_Destroy(SqListPtr L);
void List_Clear(SqListPtr L);
bool List_Empty(SqListPtr L);
int List_Size(SqListPtr L);
Status List_Retrival(SqListPtr L,int pos,ElemType * elem);
Status List_Locate(SqListPtr L,ElemType elem,int *pos);
Status List_Insert(SqListPtr L,int pos,ElemType elem);
Status List_delete(SqListPtr L,int pos);
Status List_Prior(SqListPtr L,int pos,ElemType * elem);
Status List_Next(SqListPtr L,int pos,ElemType * elem);
void List_Print(SqListPtr L);
//SqList.cpp
#include <stdio.h>
#include <stdlib.h>
#include "SqList.h"
Status List_Init(SqListPtr L)
{
Status s = fail;
if( L != NULL)
{
L->elem = (ElemType *) malloc((LIST_INIT_SIZE+1) * sizeof(ElemType));
if(L->elem)
{
L->list_size = LIST_INIT_SIZE;
L->length = 0;
s = success;
}
}
return s;
}
void List_Destroy(SqListPtr L)
{
if(L)
{
if(L->elem)
{
free(L->elem);
L->elem = NULL;
L->length = 0;
}
}
}
void List_Clear(SqListPtr L)
{
if(L)
{
L->length = 0;
}
}
bool List_Empty(SqListPtr L)
{
return (L->length == 0);
}
int List_Size(SqListPtr L)
{
return (L->length);
}
Status List_Retrival(SqListPtr L,int pos,ElemType * elem)
{
Status s = rang_error;
if(L)
{
if(pos>=1 && pos<=L->length)
{
*elem = L->elem[pos];
s = success;
}
}
return s;
}
Status List_Locate(SqListPtr L,ElemType elem,int *pos)
{
Status s = rang_error;
int i;
if(L)
{
for(i=1 ; i<=L->length ;i++)
{
if(L->elem[i] == elem)
{
*pos = i;
s = success;
break;
}
}
}
return s;
}
Status List_Insert(SqListPtr L,int pos,ElemType elem)
{
Status s =rang_error;
int i;
if(L)
{
if(pos>=1 && pos<=L->length+1)
{
if(L->length < L->list_size)
{
for(i=L->length ; i>= pos ; i--)
{
L->elem[i+1] = L->elem[i];
}
L->elem[pos] = elem;
L->length++;
s = success;
}
}
}
return s;
}
Status List_delete(SqListPtr L,int pos)
{
Status s = rang_error;
int i;
if(L)
{
if(pos>=1 && pos<=L->length)
{
for(i = pos+1; i<= L->length ; i++)
{
L->elem[i-1] = L->elem[i];
L->length--;
s = success;
}
}
}
return s;
}
Status List_Prior(SqListPtr L,int pos,ElemType * elem)
{
Status s = rang_error;
if(L)
{
if(pos>1 && pos<=L->length)
{
* elem = L->elem[pos-1];
s = success;
}
}
return s;
}
Status List_Next(SqListPtr L,int pos,ElemType * elem)
{
Status s = rang_error;
if(L)
{
if(pos>=1 && pos<L->length)
{
* elem = L->elem[pos+1];
s = success;
}
}
return s;
}
void List_Print(SqListPtr L)
{
int i;
for(i=1 ;i<=L->length ;i++)
{
printf("%d ",L->elem[i]);
}
}
//TestSqList.h
#include "SqList.h"
Status Test_CreateList(SqListPtr list,ElemType data[],int n);
Status Test_ClearList(SqListPtr list);
Status Test_RetrivalPriorNext(SqListPtr list,int pos);
Status Test_locate(SqListPtr list,ElemType e);
void Test_Size(SqListPtr list);
//TestSqList.cpp
#include <stdio.h>
#include "SqList.h"
#include "TestSqList.h"
Status Test_CreateList(SqListPtr list,ElemType data[],int n)
{
Status s = fail;
int i;
s = List_Init(list);
if(s == success)
{
for(i=1 ;i<=n ;i++)
{
s = List_Insert(list,i,data[i]);
if(s!=success)
break;
}
List_Print(list);
}
return s;
}
Status Test_ClearList(SqListPtr list)
{
Status s = fail;
if(!List_Empty(list))
{
List_Clear(list);
if(List_Empty(list))
{
s = success;
}
}
return s;
}
Status Test_RetrivalPriorNext(SqListPtr list,int pos)
{
Status s = rang_error;
ElemType e;
s = List_Retrival(list,pos,&e);
if(s == success)
{
printf("%d的元素是%d",pos,e);
s = List_Prior(list,pos,&e);
if(s == success)
{
printf("%d的直接前驱元素是%d",pos,e);
}
else
{
printf("没有直接前驱\n");
}
s = List_Next(list,pos,&e);
if(s == success)
{
printf("%d的直接后继是%d",pos,e);
}
else
{
printf("没有直接后继\n");
}
}
else
{
printf("位置不合法\n");
}
return s;
}
Status Test_locate(SqListPtr list,ElemType e)
{
Status s;
int pos;
s = List_Locate(list,e,&pos);
if(s == success)
{
printf("%d的位置是%d\n",e,pos);
}
else
{
printf("查找失败\n");
}
return s;
}
void Test_Size(SqListPtr list)
{
int len;
len = List_Size(list);
printf("线性表的长度%d\n",len);
}
//main.cpp
#include "TestSqList.h"
#include <stdio.h>
#include <stdlib.h>
int main ()
{
SqList list;
int pos,size;
ElemType e,*data;
int opt=1;
Status s;
while(opt!=6)
{
printf("请输入选项:\n");
printf("1 测试建立线性表\n");
printf("2 测试清空线性表\n");
printf("3 测试求某位置的线性表元素及前驱后继\n");
printf("4 测试查询某元素的位置\n");
printf("5 测试线性表的长度\n");
printf("6 结束程序\n");
scanf("%d",&opt);
switch (opt)
{
case 1:{
printf("线性表长度:\n");
scanf("%d",&size);
data = (ElemType *)malloc(1+size*sizeof(ElemType));
if(data == NULL)break;
printf("线性表元素:\n");
for(int i=1 ;i<=size;i++)
scanf("%d",&data[i]);
s = Test_CreateList(&list,data,size);
if(s != success)
printf("建立线性表失败\n");
free(data);
List_Destroy(&list);
break;
}
case 2:{
printf("线性表长度:\n");
scanf("%d",&size);
data = (ElemType *)malloc((1+size)*sizeof(ElemType));
if(data == NULL)break;
printf("线性表元素:\n");
for(int i=1 ;i<=size;i++)
scanf("%d",&data[i]);
s = Test_CreateList(&list,data,size);
if(s == success)
{
if(!List_Empty(&list))
{
List_Clear(&list);
if(List_Empty(&list))
{
printf("已经正确处理!\n");
}
}
}
free(data);
List_Destroy(&list);
break;
}
case 3:{
printf("线性表长度:\n");
scanf("%d",&size);
data = (ElemType *)malloc((1+size)*sizeof(ElemType));
if(data == NULL)break;
printf("线性表元素:\n");
for(int i=1 ;i<=size;i++)
scanf("%d",&data[i]);
s = Test_CreateList(&list,data,size);
if(s == success)
{
printf("输入待查找的位置:\n");
scanf("%d",&pos);
Test_RetrivalPriorNext(&list,pos);
}
free(data);
List_Destroy(&list);
break;
}
case 4:{
printf("线性表长度:\n");
scanf("%d",&size);
data = (ElemType *)malloc((1+size)*sizeof(ElemType));
if(data == NULL)break;
printf("线性表元素:\n");
for(int i=1 ;i<=size;i++)
scanf("%d",&data[i]);
s = Test_CreateList(&list,data,size);
if(s == success)
{
printf("输入待查询的元素值:\n");
scanf("%d",&e);
Test_locate(&list,e);
}
free(data);
List_Destroy(&list);
break;
}
case 5:{
printf("线性表长度:\n");
scanf("%d",&size);
data = (ElemType *)malloc((1+size)*sizeof(ElemType));
if(data == NULL)break;
printf("线性表元素:\n");
for(int i=1 ;i<=size;i++)
scanf("%d",&data[i]);
s = Test_CreateList(&list,data,size);
if(s == success)
{
Test_Size(&list);
}
free(data);
List_Destroy(&list);
break;
}
}
}
return 0;
}