编程实现 ADT List 基本操作13个(二)
ADT List如下
ADT List
{
数据对象:D = {ai|ai∈ElemSet,i=1, 2, …, n, n≥0}
数据关系:R = {<ai-1, a>|ai-1, ai∈D, i=2, …, n}
基本操作:
//1.初始化、销毁和清空操作
InitList( &L )
操作结果:构造一个空的线性表L
DestroyList( &L )
初始条件:线性表L已存在
操作结果:销毁线性表
ClearList( &L )
初始条件:线性表L已存在
操作结果:将线性表L重置为空表
//2.访问型操作
ListEmpty( L )
初始条件:线性表L已存在
操作结果:若线性表L为空表,则返回TRUE,否则返回FALSE
ListLength( L )
初始条件:线性表L已存在
操作结果:返回线性表L的元素个数
GetElem( L, i, &e )
初始条件:线性表L已存在,且1≤i≤ListLength(L)
操作结果:用参数e返回线性表L中第i个元素的值
LocateElem( L, e )
初始条件:线性表已存在
操作结果:返回线性表L中第一个与参数e相同的数据元素的位置。若这样的元素不存在,则返回0
PriorElem( L, cur_e, &pre_e )
初始条件:线性表L已存在
操作结果:若cur_e是线性表L中的数据元素,且不是第一个元素,则用pre_e返回其前驱元素,否则操作失败,pre_e无意义
ListTraverse( L )
初始条件:线性表L已存在
操作结果:从线性表第一个元素开始,依次访问并输出线性表的数据元素
//3.加工型操作
SetElem( &L, i, &e )
初始条件:线性表L已存在,且1≤i≤ListLength(L)
操作结果:将线性表L中第1个元素的值用参数e替换,并将旧值用参数e返回
InsertElem( &L, i, e )
初始条件:线性表L已存在,且1≤i≤ListLength(L)+1
操作结果:将线性表L中第i个元素的值用参数e替换,并将旧值用参数返回
DeleteElem( &L, i, &e )
初始条件:线性表L已存在,且1≤i≤ListLength(L)
操作结果:删除线性表L中第i个位置上的数据元素,并用参数e返回其元素值,原来第i+1个到第n个元素依次向前移动一个位置,线性表L的长度减1
} //ADT List
使用链式结构实现
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct LNode
{
int data; //数据域
struct LNode *next; //指针域
} LNode, *LinkList;
typedef struct SListInfo
{
LinkList head; //表头结点指针
LinkList tail; //表尾结点指针
LNode *pCurNode; //当前结点指针位置
int length; //单链表的长度(元素个数)
} SListInfo;
void InitList( SListInfo &L )
{ //初始化单链表
L.head = (LNode *)malloc(sizeof(LNode)); //申请头结点存储空间
if( L.head == NULL )
cout<<"error1"<<endl; //存储空间申请失败
L.head->next = NULL; //头结点后无其他结点
L.tail = L.head; //尾结点指针也指向头结点
L.pCurNode = L.head; //当前指针也指向头结点
L.length = 0; //单链表长度为零
} //InitList
void DestroyList( SListInfo &L )
{ //销毁单链表
LNode *p;
if( L.head->next != NULL)
{
while( L.head->next != NULL ) //从头结点开始逐个释放链表中的结点
{
p = L.head->next;
L.head->next = p->next;
free(p);
}
}
free(L.head); //释放头结点
L.head = NULL;
L.tail = NULL;
L.pCurNode = NULL;
L.length = 0;
} //DestroyList
void ClearList( SListInfo &L )
{ //清空单链表
LNode *p;
while( L.head->next != NULL ) //从头结点的后继开始逐个释放链表中的结点
{
p = L.head->next;
L.head->next = p->next;
free(p);
}
L.head->next = NULL; //重置为空表,不释放头结点
L.length = 0;
} //ClearList
bool ListEmpty( SListInfo L )
{ //判断是否为空表
if( L.head->next == NULL )
return true;
else
return false;
} //ListEmpty
int ListLength( SListInfo L )
{ //获取链表中的元素个数
return L.length; //返回元素个数
} //ListLength
int GetElem( SListInfo L, int i, int &e )
{ //获取单链表第i个数据元素
if( i < 1 || i > L.length ) //参数检查
cout<<"error2"<<endl;
LNode *p;
L.pCurNode = L.head->next;
int j = 1; //计数器
while( j < i ) //还未到达第i个元素,指针和计数器同步更新
{
L.pCurNode = L.pCurNode->next;
j ++;
}
e = L.pCurNode->data; //获得数据元素
return e; //返回e
} //GetElem
int LocateElem( SListInfo L, int e )
{ //返回链表中第一个与参数e相同的数据元素的位置
L.pCurNode = L.head;
int i = 0; //记录数据元素的物理位置(头结点位置为0)
while( L.head->next != NULL )
{
L.pCurNode = L.pCurNode->next; //向后移动
i ++;
if( L.pCurNode->data == e ) //找到与e相同的数据元素
{
return i; //返回位置
break;
}
}
} //LocateElem
int PriorElem( SListInfo L, int cur_e, int &pre_e )
{ //cur_e是链表中的数据元素且不是第一个数据元素,用pre_e返回其前驱元素
if( L.head->next == NULL )
cout<<"error3"<<endl;;
L.pCurNode = L.head->next;
if( cur_e != L.pCurNode->data ) //cur_e不是第一个数据元素
{
while( L.pCurNode->next != NULL )
{
if( L.pCurNode->next->data == cur_e ) //找到cur_e
{
pre_e = L.pCurNode->data; //获取前驱元素并返回
return pre_e;
}
L.pCurNode = L.pCurNode->next; //向后移动
}
}
else
cout<<"error4"<<endl;
} //PriorElem
int NextElem( SListInfo L, int cur_e, int &next_e )
{ //cur_e是链表中的数据元素且不是最后一个数据元素,用next_e返回其后继元素
if( L.head->next == NULL )
cout<<"error5"<<endl;;
L.pCurNode = L.head->next;
int pre_e;
if( cur_e != L.tail->data ) //不是最后一个元素
{
while( L.pCurNode != NULL )
{
if( L.pCurNode->data == cur_e ) //找到cur_e
{
pre_e = L.pCurNode->next->data; //获取后继元素并返回
return pre_e;
}
}
}
} //NextElem
void ListTraverse( SListInfo L )
{ //从链表的第一个元素开始,依次访问并输出链表的数据元素
if( L.head->next == NULL )
cout<<"error6"<<endl;;
L.pCurNode = L.head->next;
while( L.pCurNode->next != NULL)
{
cout<<L.pCurNode->data<<endl; //输出元素
L.pCurNode = L.pCurNode->next;
}
cout<<L.pCurNode->data<<endl; //输出表尾元素
} //ListTraverse
int SetElem( SListInfo &L, int i, int &e )
{ //将链表中第i个元素的值用参数e替代,并将旧值用参数e返回
if( L.head->next == NULL )
cout<<"error7"<<endl;;
L.pCurNode = L.head->next;
int j = 1;
while( L.pCurNode->next != NULL )
{
if( j == i ) //找到第i个元素
{
e = e + L.pCurNode->data;
L.pCurNode->data = e - L.pCurNode->data;
e = e - L.pCurNode->data;
return e;
}
else
{
L.pCurNode = L.pCurNode->next;
j ++;
}
}
} //SetElem
void InsertElem( SListInfo &L, int i, int e )
{ //在第i个位置后插入新的数据元素e
LNode *s = (LNode *)malloc(sizeof(int)); //申请新的结点
if( s == NULL )
cout<<"error8"<<endl;; //申请失败
s->data = e; //将e存入新结点
L.pCurNode = L.head;
for( ; i > 0; i -- ) //找到位置i
{
if( L.pCurNode->next == NULL)
{
cout<<"error9"<<endl;
break;
}
L.pCurNode = L.pCurNode->next;
}
if( L.pCurNode->next != NULL)
{
s->next = L.pCurNode->next; //插入元素e
L.pCurNode->next = s;
L.length += 1; //链表长度+1
}
else
{
L.pCurNode->next = s;
s->next = NULL;
L.length += 1;
L.tail = s;
}
} //InsertElem
int DeleteElem( SListInfo &L, int i, int &e )
{ //删除第i个位置上的数据元素,并用e返回其元素值
if( L.head->next == NULL ) //无结点可删除
cout<<"error10"<<endl;
L.pCurNode = L.head->next;
LNode *p;
for( ; i > 1; i -- ) //找到位置i
{
p = L.pCurNode;
L.pCurNode = L.pCurNode->next;
}
e = L.pCurNode->data;
p->next = L.pCurNode->next;
if( L.pCurNode->next == NULL ) //若位置i是表尾则前移尾指针
L.tail = p;
p = L.pCurNode;
free(p);
L.length -= 1; //链表长度减1
return e;
} //DeleteElem
int main()
{
SListInfo L;
int i, n, x;
int &e = x;
cout<<"-进行初始化操作-"<<endl;
InitList(L); //初始化
cout<<"-请输入链表长度-"<<endl;
cin>>n;
cout<<"-请逐个输入链表数据元素-"<<endl;
for( i = 0; i <= n; i ++ )
{
cin>>x;
InsertElem(L, i, e); //添加元素
}
if( ListEmpty(L) == 1 ) //判断是否为空表
cout<<"单链表为空表"<<endl;
else
cout<<"单链表不是空表"<<endl;
cout<<"输出单链表如下:"<<endl;
ListTraverse(L); //输出单链表
cout<<endl;
cout<<"-进行清空操作-"<<endl;
ClearList(L); //清空单链表
if( ListEmpty(L) == 1 ) //再次判断是否为空表
cout<<"单链表为空表"<<endl;
else
cout<<"单链表不是空表"<<endl;
cout<<endl;
for( i = 0; i <= 4; i ++ )
{
InsertElem(L, i, e); //再次添加元素
n += 2;
}
cout<<"输出单链表如下:"<<endl;
ListTraverse(L);
cout<<endl;
cout<<"单链表长度为:";
cout<<ListLength(L); //获取单链表长度
cout<<endl;
i = 2;
cout<<"第"<<i<<"个数据元素为:";
cout<<GetElem(L, i, e); //获取第i个数据元素
cout<<endl;
cout<<"元素"<<e<<"所在的位置:";
cout<<LocateElem(L, e); //获取数据位置
cout<<endl;
cout<<"元素"<<e<<"的前驱元素为:";
cout<<PriorElem(L, e, e); //获取e的前驱元素
cout<<endl;
cout<<"元素"<<e<<"的后继元素为:";
cout<<NextElem(L, e, e); //获取e的后继元素
cout<<endl;
n = 100;
e = n;
cout<<"第"<<i<<"个元素被"<<e<<"替换前的旧值为:";
cout<<SetElem(L, i, e); //将第i个元素用e替换
cout<<endl;
cout<<"输出单链表如下:"<<endl;
ListTraverse(L);
cout<<endl;
i++;
cout<<"将要删除的第"<<i<<"个元素为:";
cout<<DeleteElem(L, i, e); //删除第i个元素
cout<<endl;
cout<<"输出单链表如下:"<<endl;
ListTraverse(L);
cout<<endl;
cout<<"-进行销毁操作-"<<endl;
DestroyList(L); //销毁单链表
}
以上。