什么是线性表
1、同于一个问题可以有不同的表示(存储)方法
2、有一类共性问题:有序线性序列的组织和管理
线性表:由同类型 数据元素 构成 有序序列 的线性结构
*表中元素个数称为线性表的长度
*线性表没有元素时,称为空表、
*表起始位置称表头,表结束位置称表尾
线性表的顺序存储实现
利用数组的连续存储空间顺序存放线性表的各元素
主要操作的实现
1、初始化(建立空的顺序表)
List MakeEmpty()
{
List Ptrl;
Ptrl = (List)malloc(sizeof(struct LNode));
Ptrl->Last = -1;
return Ptrl;
}
2、查找
template<class ElementType, class List>
int Find(ElementType X, List Ptrl)
{
int i = 0;
while (i <= Ptrl->Last && Ptrl->Data[i] != X)
i++;
if (i > Ptrl->Last) return -1;
else return i;
}
3、插入
template<class ElementType,class List>
int 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--)
{
Ptrl->Data[j + 1] = Ptrl - > Data[j];
}
Ptrl -> Data[i - 1] = X;
Ptrl->Last++;
return;
}
4、删除
template<class ElementType, class List>
void Delete(int i, List Ptrl)
{
int j = 0;
if (i < 1 || i >Ptrl->Last + 1)
{
printf("不存在第%d个元素", i);
return;
}
for (j = i; j <= Ptrl->Last; j++)
{
Ptrl->Data[j - 1] = Ptrl - > Data[j];//将元素向前移动
}
Ptrl->Last--;
return;
}
线性表的链式存储实现
不要求逻辑上相邻的两个元素物理上也相邻;通过 链 建立起数据元素之间的逻辑关系
*插入、删除不需要移动数据元素,只需要修改 链
typedef struct LNode *List;
struct LNode {
ElementType Data;
List Next;
};
struct Lnode L;
List Ptrl;
1、求表长
int Length(List Ptrl)
{
List p = Ptrl;
int j = 0;
while (p)
{
p = p->Next;
j++;
}
return j;
}
2、查找
①按序号找
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;
else return NULL;
}
②按值查找
int Find(ElementType X, List Prtl)
{
List p = Ptrl;
while (p != NULL && p->Data != X)
{
p = p->Next;
}
return p;
}
3、插入
List Insert(ElementType X, int i, List Prtl)
{
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);
if (p == NULL)
{
printf("参数i错");
return NULL;
}
else {
s = (List)malloc(sizeof(struct LNode));
s->Data = X;
s->Next = p->Next;
s->Next = Ptrl;
return s;
}
}
4、删除操作实现
List Delete(int i, List Ptrl)
{
List p, s;
if (i == 1)
{
s = Ptrl;
if (Ptrl != NULL) Ptrl = Ptrl->Next;
else return NULL;
free(s);
return Ptrl;
}
p = FindKth(i - 1, Ptrl);
if (p == NULL)
{
printf("第%d个节点不存在", i - 1); return NULL;
}
else if (p->Next == NULL)
{
printf("第%d个节点不存在", i); return NULL;
}
else {
s = p->Next;
p->Next = s->Next;
free(s);
return Ptrl;
}
}
广义表
广义表时线性表的推广
对于线性表而言,n个元素都可以是基本的单元素
广义表中,这些元素不仅可以是单元素,也可以是另一个广义表
typedef struct GNode*GList;
struct GNode {
int Tag;
union {
ElementType Data;
GList SubList;
}; URegion;
GList Next;
};
多重链表: 链表中的节点可能同时隶属于多个链
1、多重链表中结点的指针域会有多个
2、但包含两个指针域的链表并不一定是多重链表,比如在双向链表不是多重链表
多重链表有广泛的用途:
基本上如树,图这样相对复杂的数据结构都可以采用多重链表方式存储
堆栈的抽象数据类型描述
堆栈:具有一定操作约束的线性表
只在一端(栈顶)做插入、删除
插入数据:入栈PUSH
删除数据:出栈POP
先入后出:LIFO
栈的顺序存储实现
栈的顺序存储结构通常由一个一维数组和一个记录栈顶元素位置的变量组成
#define MaxSize<储存数据元素的最大个数>
typedef struct SNode *Stack;
struct SNode {
ElementType Data[MaxSize];
int Top;
};
1、入栈
void Push(Stack PtelS, ElementType item)
{
if (Ptrl->Top == MaxSize - 1)
{
printf("堆栈满"); return;
}
else {
PtrlS->Data[++(PtrlS->Top)] = item;
return;
}
}
2、出栈
ElementType Pop(Stack PtrS)
{
if (PtrS->Top == -1)
{
prinf("堆栈空");
return ERROR;
}
else
return (PtrS->Data[(PtrS->Top)--]);
}
栈的链式存储结构实际上就是一个单链表,叫做链栈。插入和删除操作只能在链栈的栈顶进行。