前言
线性表
线性表(List):零个或者多个数据元素的集合
线性表的抽象数据类型:
ADT:线性表(list) data 线性表的数据对象集合为{a1,a2,…an},每个元素的类型均为datatype,其中除第一个元素a1和最后一个元素an外每一个元素有且只有一个前驱后继,数据元素都是一一对应的关系 Operation InitList(*L):初始化操作,建立一个空的线性表L。 ListEmpty(L):判断一个线性表是否为空,为空返回真,否则返回假。 ClearList(*L):线性表清空。 GetElem(L,I,*e):线性表L中的第I个元素值返回给e LocateEleme(L,e):线性表L中查找与给定e元素相等的元素,如果查找成功,返回该元素在表中序号,否则返回0表示失败。 ListInsert(*L,I,e):线性表第i个位置插入新元素e ListDelete(*L,I,*e):删除线性表第i个元素,并用e返回其值 ListLength(L):返回线性表的长度 endADT
|
线性表的顺序结构:
线性表的顺序存储结构:指的是用一段地址连续的存储单元依次存储线性表的数据元素
线性表的顺序存储的结构代码:
typedef struct { ElemType data[MAXSIZE]; int length; }SqList;
|
顺序存储结构3个属性:
- 存储空间的起始位置:数据data,它的存储位置就是存储空间的存储位置
- 线性表的最大存储容量:数据长度MaxSize
- 线性表的最大长度:length
但是"数组长度"和"线性表长度"并不是一个东西
数组长度是值存放线性表的存储空间的长度,这个值一般情况下在存储分配完成后是不变的.
线性表的长度是指线性表中数据元素的个数,随着线性表的插入和删除这个值是会改变的.
顺序存储结构的插入和删除:
获取元素操作:
#define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0
Status GetElem(SqList L,int i,ElemType *e) { if(L.length==0 || i<1 || i>L.length) return ERROR; *e=L.data[i-1];
return OK; }
|
插入操作:
插入算法的思路:
- 如果插入位置不合理,抛出异常
- 如果线性表长度大于等于数组长度,则抛出异常或者动态增加容量
- 从最后一个元素开始往前变量i个元素,分别将它们往后移一个位置
- 将要插入的元素填入位置i出
- 表长度+1
Status ListInsert(SqList *L,int i,ElemType e) { int k; if (L->length==MAXSIZE) return ERROR; if (i<1 || i>L->length+1) return ERROR;
if (i<=L->length) { for(k=L->length-1;k>=i-1;k--) L->data[k+1]=L->data[k]; } L->data[i-1]=e; L->length++;
return OK; }
|
删除操作:
删除算法的思路:
- 如果删除位置不合理,抛出异常
- 取出删除元素
- 从删除元素位置开始遍历到最后一个元素的位置,分别将它们都往前移动一位
- 表长度-1
Status ListDelete(SqList *L,int i,ElemType *e) { int k; if (L->length==0) return ERROR; if (i<1 || i>L->length) return ERROR; *e=L->data[i-1]; if (i<L->length) { for(k=i;k<L->length;k++) L->data[k-1]=L->data[k]; } L->length--; return OK; }
|
线性表顺序存储结构的优缺点:
优点:
- 无须为表示表中元素之间的逻辑关系而增加额外的存储空间
- 可以快速存取表中任一位置的元素
缺点:
- 插入和删除需要移动大量的元素
- 当线性表长度变化较大的时候,难以确定存储空间的容量
- 造成存储空间的"碎片"
完整代码
顺序结构完整代码如下:
#include "stdio.h"
#include "stdlib.h" #include "math.h" #include "time.h"
#define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0
#define MAXSIZE 20 typedef int ElemType; typedef struct { ElemType data[MAXSIZE]; int length; }SqList;
typedef int Status;
Status visit(ElemType c) { printf("%d ",c); return OK; }
Status InitList(SqList *L) { L->length=0; return OK; }
Status ListEmpty(SqList L) { if(L.length==0) return TRUE; else return FALSE; }
Status ClearList(SqList *L) { L->length=0; return OK; }
int ListLength(SqList L) { return L.length; }
Status GetElem(SqList L,int i,ElemType *e) { if(L.length==0 || i<1 || i>L.length) return ERROR; *e=L.data[i-1];
return OK; }
int LocateElem(SqList L,ElemType e) { int i; if (L.length==0) return 0; for(i=0;i<L.length;i++) { if (L.data[i]==e) break; } if(i>=L.length) return 0;
return i+1; }
Status ListInsert(SqList *L,int i,ElemType e) { int k; if (L->length==MAXSIZE) return ERROR; if (i<1 || i>L->length+1) return ERROR;
if (i<=L->length) { for(k=L->length-1;k>=i-1;k--) L->data[k+1]=L->data[k]; } L->data[i-1]=e; L->length++;
return OK; }
Status ListDelete(SqList *L,int i,ElemType *e) { int k; if (L->length==0) return ERROR; if (i<1 || i>L->length) return ERROR; *e=L->data[i-1]; if (i<L->length) { for(k=i;k<L->length;k++) L->data[k-1]=L->data[k]; } L->length--; return OK; }
Status ListTraverse(SqList L) { int i; for(i=0;i<L.length;i++) visit(L.data[i]); printf("\n"); return OK; }
void unionL(SqList *La,SqList Lb) { int La_len,Lb_len,i; ElemType e; La_len=ListLength(*La); Lb_len=ListLength(Lb); for (i=1;i<=Lb_len;i++) { GetElem(Lb,i,&e); if (!LocateElem(*La,e)) ListInsert(La,++La_len,e); } }
|