数据结构与算法(陈越版)第二讲 线性结构—线性表及其表现
一、线性表的定义
线性表(Linear List):由同一类型的数据元素构成的有序序列的线性结构。
线性表中元素的个数称为线性表的长度
表起始位置称为:表头,表结束位置称为:表尾。
二、线性表的抽象数据类型描述
类型名称:线性表(List)
数据对象集: 线性表是 n ( ≥ n ) n ( \geq n) n(≥n)个元素构成的有序序列 ( a 1 , a 2 , . . . , a n ) (a_1, a_2,...,a_n) (a1,a2,...,an)
操作集:初始化,查找,插入,删除等等。
三、线性表的实现
3.1、线性表的顺序存储实现
# include<iostream>
using namespace std;
# define MaxSize 100
# include<malloc.h>
typedef int ElementType;
// 创建顺序储存的结构体
typedef int Position;
struct LNode
{
ElementType Data[MaxSize];
Position Last;
};
typedef LNode * List;
// 初始化
List CreateList()
{
List L = (List)malloc(sizeof(struct LNode));
L->Last = -1;
return L;
}
// 插入
void Insert(ElementType x, int i, List L)
{
//判断是否已经满了
if (L->Last == MaxSize - 1)
{
cout << "线性表已经满了" << endl;
return;
}
if (i < 0 || i >= MaxSize)
{
cout << "插入不合法" << endl;
return;
}
// 插入数据前,移动i-1之后的数据
for (int j = L->Last; j >= i; --j)
{
L->Data[j + 1] = L->Data[j];
}
L->Data[i] = x;
++L->Last;
return;
}
// 按值查找
int Findx(ElementType x, List L)
{
int i = 0;
while (i <= L->Last && L->Data[i] != x)
++i;
if (i > L->Last)
{
cout << "查找元数不在线性表中" << endl;
return -1;
}
else
return i;
}
// 按位数查找,即:查找下标为k个元素
ElementType FindK(int k, List L)
{
if (k < 0 || k > L->Last)
{
cout << "下标为" << k << "的元素不存在" << endl;
return -1;
}
else
return L->Data[k];
}
// 删除 从L中删除下标为i的值,不返回其值
void Delete(int i, List L)
{
//位置不合适
if (i < 0 || i > L->Last)
{
cout << "下标为" << i << "的元素不存在" << endl;
}
// 移动数据直接覆盖
for (int j = i; j < L->Last; ++j)
{
L->Data[j] = L->Data[j + 1];
}
--L->Last;
return;
}
int main()
{
List L = CreateList(); // 初始化
// 插入数据成功
Insert(11, 0, L);
Insert(25, 0, L);
Insert(33, 0, L);
Insert(77, 0, L);
Insert(85, 2, L);
for (int i = 0; i <= L->Last; ++i)
{
cout << L->Data[i] << " ";
}
cout << endl;
// 插入失败
Insert(60, 102, L);
// 按值查找成功
int a = Findx(25, L);
cout << "25的位置在:" << a << endl;
// 按值查找失败
a = Findx(90, L);
// 按下标查找成功
int X = FindK(4, L);
cout << "下标为4的元素是: " << X << endl;
// 按下标查找失败
X = FindK(20, L);
// 删除成功
Delete(3, L);
cout << "删除之后的排序" << endl;
for (int i = 0; i <= L->Last; ++i)
{
cout << L->Data[i] << " ";
}
cout << endl;
// 删除失败
Delete(20, L);
return 0;
}
3.2、线性表的链式储存方式
# include<iostream>
# include<malloc.h>
using namespace std;
// 构建链式结点结构体
typedef struct LNode * PLNode;
typedef int ElementType;
typedef int Position;
struct LNode
{
ElementType Data;
PLNode Next;
};
typedef PLNode List;
// 初始化
List CreateList()
{
List L = (List)malloc(sizeof(struct LNode));
L = NULL;
return L;
}
// 求链表长度
int Length(List L)
{
int count = 0;
while (L)
{
L = L->Next;
++count;
}
return count;
}
// 位置查找
List FindK(int K, List L)
{
int i = 1;
List P = L;
while (P && i < K)
{
P = P->Next;
++i;
}
if (i == K)
return P;
else
{
cout << "查找失败" << endl;
return NULL;
}
}
// 插入数据
List Insert(ElementType X, int i, List L)
{
List P = L;
List s,p;
p = (List)malloc(sizeof(struct LNode));
p->Data = X;
p->Next = NULL;
if (i == 1)
{
p->Next = P;
return p;
}
s = FindK(i - 1, P);
if(s == NULL)
{
cout << "插入位置有误" << endl;
return NULL;
}
else
{
p->Next = s->Next;
s->Next = p;
}
return P;
}
// 按数值查找
int Findx(ElementType X, List L)
{
int i = 1;
List P = L;
while (P && P->Data != X)
{
P = P->Next;
++i;
}
if (P)
return i;
else
cout << "查找失败" << endl;
return 0;
}
// 删除链表的第i个结点
List Delete(int i, List L)
{
List tmp, s;
if (i == 1)
{
tmp = L;
if (L)
L = L->Next;
else
return NULL;
free(tmp);
return L;
}
s = FindK(i-1, L);
if (!s || !(s->Next))
{
cout << "释放的位置节点错误" << endl;
return NULL;
}
else
{
tmp = s->Next; // 第i个结点
s->Next = tmp->Next;
free(tmp);
return L;
}
}
// 按链表顺序打印L的元素
void print(List L)
{
while (L)
{
cout << L->Data << " ";
L = L->Next;
}
cout << endl;
}
int main()
{
List L = CreateList();
int i = 0;
List P;
// 插入数据
L = Insert(22, 1, L);
L = Insert(50, 1, L);
L = Insert(64, 1, L);
L = Insert(70, 2, L);
L = Insert(55, 4, L);
// 计算长度
int len = Length(L);
cout << "链表长度为:" << len << endl;
// 打印列表数值
print(L);
// 位置查找 成功
P = FindK(3, L);
cout << "第3个结点元素为:" << P->Data << endl;
// 位置查找 失败
P = FindK(7, L);
// 元素查找 成功
Position pt = Findx(22, L);
cout << "22这个元素在第" << pt << "结点" << endl;
// 元素查找 失败
pt = Findx(80, L);
// 删除结点 成功
L = Delete(2, L);
cout << "删除第二个结点后的链表排序:" << endl;
print(L);
// 删除 失败
L = Delete(7, L);
return 0;
}