数据结构-线性表-线性表及其表现
2.1.2线性表及顺序存储
线性表的顺序存储实现
利用数组的连续存储空间顺序存放线性表的各元素
typedef struct LNode *List;
struct LNode
{
ElementType Data[MAXSIZE];
int Last; //最后一个数的位置
};
struct LNode L; //定义结构体变量
List PtrL; //定义结构体指针
定义结构体变量,访问成员时就用 .
定义结构体指针,访问成员时就用 ->
访问下标为i的元素: L.Data[i] 或 Ptrl->Data[i]
线性表主要操作的实现
1.初始化(建立空的顺序表)
List MakeEmpty()
{
List PtrL;
PtrL = (List)malloc(sizeof(struct LNode)); //申请内存
PtrL -> Last = -1; //表中无元素
return PtrL; //返回结构指针
}
2.查找
int Find(ElementType X,List PtrL)
{
int i = 0;
while(i <= PtrL -> Last && PtrL -> Data[i] != X)
i++;
if(i > Ptrl -> Last) return -1; //如果没找到,返回-1
else return i;
}
3.插入(第i(i <= i <= n + 1)个位置上插入一个值为X的新元素)
void Insert(ElementType X,int i,List PtrL)
{
int j;
if(PtrL -> Last == MAXSIZE - 1) //表空间已满,不能插入
{ printf("表满");
return;
}
if(i < 1 || i > PtrL -> Last + 2)
{ printf("位置不合法");
return ;
}
for(j = PtrL -> Last; j >= i - 1; j--) //将第i个下标开始倒序向后移动1位
Ptrl -> Data[j+1] = PtrL -> Data[j];
Ptrl -> Data[i - 1] = X; //插入新元素
PtrL -> Last ++; //Last仍指向最后元素
return ;
}
4.删除(删除表的第i(i <= i <= n)个位置上的元素
void Delete(int i,List PtrL)
{
int j;
if(i < 1 || i > PtrL -> Last + 1) //检查空表及删除位置的合法性
{
printf("不存在第%d个元素",i);
return ;
}
for(j = i ; j <= PtrL -> Last;j++) //从第i位开始,往前移动一位
PtrL -> Data[j - 1] = PtrL -> Data[j];
PtrL -> Last--;
return ;
}
2.1.4 线性表的链式存储实现
基本形式
typedef struct LNode *List;
struct LNode
{
ElementType Data;
List Next; //指向下一个数的指针
};
struct LNode L;
List PtrL;
链式表的主要操作
1.求表长
int Length(List PtrL)
{
List p = PtrL; //p设置为表头
int j = 0;
while(p)
{
p = p -> Next;
j++;
}
return j;
}
2.查找
按序号查找,查找第K个数
List FindKth(int K,List PtrL)
{
List p = PtrL;
int i = 1;
while(p != NULL && i < K)
{
p = p -> Next;
i++;
}
if(i == K) return p; //找到第K个,返回指针p
else return NULL;
}
按值查找
List FindKth(ElementType X,List PtrL)
{
List p = PtrL;
while(p != NULL && p -> Data != X)
{
p = p -> Next;
}
return p;
}
3.插入(在第i - 1个节点后插入一个值为X的新节点)
List Insert(ElementType X,List PtrL)
{
List p ,s;
if(i == 1) //新节点在表头
{
s = (List)malloc(sizeof(struct LNode));
s -> Data = X;
s -> Next = PtrL;
return s;
}
p = FindKth(i - 1,PtrL); //查找第i-1个节点
if(p == NULL)
{
printf("参数错");
return NULL;
}
else
{
s = (List)malloc(sizeof(struct LNode));
s -> Data = X;
s -> Next = p -> Next; //新节点插入在第i - 1个节点的后面
p -> Next = s;
return PtrL;
}
}
4.删除(删除链表的第i(1 <= i <= n)个位置上的节点)
List Delete(int i,List PtrL)
{
List p ,s;
if(i == 1) //要删除的节点在表头
{
s = PtrL; //s指向第一个节点
if(PtrL != NULL) PtrL = PtrL -> Next;
else return NULL;
free(s);
return PtrL;
}
p = FindKth(i - 1,PtrL); //查找第i-1个节点
if(p == NULL)
{
printf("第%d个节点不存在",i - 1);
return NULL;
}
else if(p -> Next == NULL)
{
printf("第%d个节点不存在",i);
return NULL;
}
else
{
s = p -> Next; //s指向第i个节点
p -> Next = s -> Next;
free(s);
return PtrL;
}
}
2.1.6广义表
广义表是线性表的推广
对于线性表而言,n个元素都是基本的单元素
广义表中,这些元素不仅可以是单元素也可以是另一个广义表
typedef struct GNode *GList;
struct GNode
{
int Tag; //标志域:0表示节点是单元素,1表示节点是广义表
union //子表指针域Sublist与单元素数据域Data复用,即共用存储空间
{
ElementType Data;
GList SubList;
}URegion;
GList Next; //指向后继节点
};
多重链表
多重链表:链表中节点可能同时隶属于多个链
用多重链表–十字链表来存储稀疏矩阵
只存储矩阵非0元素项
节点的数据域:行坐标Row、列坐标Col、数值Value
每个节点通过两个指针域串联起来
行指针:Right
列指针: Down