一,线性表的定义及其实现
1.线性表及顺序结构
管理一个有序的线性序列,归结为线性表问题
线性表(Linear List):由同类型数据元素构成有序序列的线性结构
- 表中元素个数被称为线性表的长度
- 线性表没有元素时被称为空表
- 表起始位置称为表头,结束位置为表尾
2.线性表的抽象数据类型描述
类型名称:线性表
数据对象集:线性表是n个元素构成的有序序列
操作集:线性表L -> List,整数i表示位置,元素X -> ElementType
- List MakeEmpty(): 初始化一个空线性表L;
- ElementType FindKth( int K, List L): 根据位序K,返回相应元素 ;
- int Find( ElementType X,List L): 在线性表L中查找X的第一次出现位置;
- void Insert( ElementType X, int i, List L): 在位序i前插入一个新元素X;
- void Delete(int i, List L): 删除指定位序i的元素;
- int Length( List L): 返回线性表L的长度n。
3.线性表的顺序存储实现
数组
#define ElemnetType int
#define MAXSIZE 100
typedef struct LNode
{
ElemnetType Data[MAXSIZE];
int Last;
}List,*pList;
List L;
pList pL;
访问下标为i的元素:L.Data[i] | pL->Data[i]
线性表的长度:L.Last+1 | pL->Last+1
链表
typedef struct _node
{
int value;
struct _node* next;
}Node, * pNode;
4.主要操作的实现
(1)数组
利用数组的连续存储空间顺序存放线性表的各元素
1)初始化(建立空的顺序表)
pList MakeEmpty()
{
pList pL;
pL = (pList)malloc(sizeof(struct LNode));
pL->Last = -1;
return pL;
}
2)查找
int Find(ElemnetType X, pList pL)
{
int i = 0;
while (i<=pL->Last&&pL->Data[i]!=X)
i++;
if (i > pL->Last)
return -1;
else
return i;
}
3)插入(第i(1<=i<=n+1)个位置上插入一个值为X的新元素)
void Insert(ElemnetType X, int i, pList pL)
{
int j;
if (pL->Last == MAXSIZE - 1)//表空间已满
{
printf("Full");
return;
}
if (i<1||i>pL->Last+2)//插入位置错误
{
printf("Error");
return;
}
for (j = pL->Last; j >= i - 1; j--)
pL->Data[j + 1] = pL->Data[j];//后移
pL->Data[i - 1] = X;//插入新元素
pL->Last++; //Last指向最后元素
return;
}
4)删除(删除表的第i(1<=i<=n)个位置上的元素)
void Delete(int i, pList pL)
{
int j;
if (i<1||i>pL->Last+1)//检查删除位置合理性
{
printf("不存在第%d个元素", i);
return;
}
for (j = i; j <= pL->Last; j++)
pL->Data[j - 1] = pL->Data[j];//将插入位置后的元素前移
pL->Last--;//Last仍指向最后元素
return;
}
(2)链表
不要求逻辑上相邻的两个元素物理上也相邻;通过“链”建立起数据元素之间的逻辑关系。
- 插入,删除不需要移动数据元素,只需要修改“链”。
1) 求表长
int Length(pNode pL)
{
pNode head = pL;//head指向表的第一个节点
int j = 0;
while (head)//head!=NULL
{
head = head->next;
j++;
}
return j;//返回长度
}
2)查找
按序号查找:
pNode FindKth(int K, pNode pL)
{
pNode p = pL;
int i = 1;
while (p!=NULL&&i<K)
{
p = p->next;
i++;
}
if (i == K)
return p;
else
return NULL;
}
按值查找:
pNode Find(ElemnetType X, pNode pL)
{
pNode p = pL;
while (p!=NULL&&p->value!=X)
{
p = p->next;
}
return p;
}
3)插入(第i(1<=i<=n+1)个位置上插入一个值为X的新元素)
(1)先构造一个新结点,用s指向;
(2)再找到链表的第i-1个结点,用p指向;
(3)然后修改指针,插入结点(p之后插入新结点是s)
s->Next=p->Next; p->Next=s;
pNode Insert(ElementType X, int i, pNode pL)
{
pNode p, s;
if (i == 1) /* 新结点插入在表头 */
{
s = (pNode)malloc(sizeof(struct LNode));/*申请,填装新结点*/
s->value = X;
s->next = pL;
return s;/*返回新表头指针*/
}
p = FindKth(i - 1, pL);/*查找第i-1个结点*/
if (p == NULL)/*第i-1个不存在,不能插入*/
{
printf("参数错误");
return NULL;
}
else
{
s = (pNode)malloc(sizeof(struct LNode));/*申请填装新结点*/
s->value = X;
s->next = p->next;/*新结点插入在第i-1个结点的后面*/
p->next = s;
return pL;
}
}
4)删除(删除表的第i(1<=i<=n)个位置上的元素)
(1)先找到链表的第i-1个结点,用p指向;
(2)再用s指针指向被删除的结点(p的下一个结点)
(3)然后修改指针,删除s所指结点
(4)最后释放s所指结点的空间
pNode Delete(int i, pNode pL)
{
pNode p, s;
if (i == 1) /*若要删除的是表的第一个结点*/
{
s = pL; //s指向第一个结点
if (pL != NULL) //从链表中删除
pL = pL->next;
else
return NULL;
free(s); //释放结点
return pL;
}
p = FindKth(i - 1, pL); /*查找第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 pL;
}
}