线性表
顺序表示
定义:
#define MAXSIZE 100 //最大长度
typedef struct
{
ElemType * elem; //指向线性表的基地址
int length; //线性表当前长度
}SqList;
相关函数:
C语言:
malloc(m)
开辟 m 字节长度的地址空间,并返回这段空间的首地址。
sizeof(x)
计算变量 x 的长度。
free(p)
释放指针 p 所指变量的存储空间,即彻底删除一个变量。
C++:new
int *p1 = new int;
//或者
int *p1 = new int(10);
//删除
delete p1;
初始化线性表
参数用引用
Status InitList_Sq(SqList &L) //构造一个空的顺序表L
{
L.elem = new ElemType[MAXSIZE]; //为顺序表分配空间
if(! L.elem)
{
exit(OVERFLOW); //存储分配失败
}
L.length = 0;
return OK;
}
参数用指针
Status InitList_Sq(SqList *L) //构造一个空的顺序表L
{
L -> elem = new ElemType[MAXSIZE]; //为顺序表分配空间
if( ! L -> elem)
{
exit(OVERFLOW); //存储空间分配失败
}
L -> length = 0;
return OK;
}
销毁线性表L
void DestroyList(SqList &L)
{
if(L.elem)
{
delete[] L.elem; //释放存储空间
}
}
清空线性表L
void ClearList(SqList &L)
{
L.length = 0; //将线性表的长度置为 0
}
判断线性表L的长度
int GetLength(SqList L)
{
return (L.length);
}
判断线性表L是否为空
int IsEmpty(SqList L)
{
if(L.length == 0)
{
return 1;
}
else
{
return 0;
}
}
取值(根据位置 i 获取相应位置数据元素的内容)
//获取线性表L中的某个数据元素的内容
int GetElem(SqList L,int i,ElemType &e)
{
if(i < 1 || i > length)
{
return ERROR;
}
//判断 i 值是否合理,若不合理,返回ERROR
e = L.elem[i-1]; //第 i-1 的单眼存储着第 i 个数据
return OK;
}
查找(根据指定数据获取数据所在的位置)
//在线性表 L 中查找值为 e 的数据元素
int LocateElem(SqList L,ElemType e)
{
for( i = 0; i < L.length; i++)
{
if(L.elem[i] == e)
{
return i+1;
}
}
return 0;
}
在线性表L中第i个元素之前插入数据元素e
Status ListInsert_Sq(SqList &L, int i, ElemType e)
{
int j;
if(i<1 || i > L.length+1)
{
return RERROR; // i 值不合法
}
if(L.length == MAXSIZE)
{
return ERROR; //当前存储空间已满。
}
for( j=L.length-1; j >= i-1; j--)
{
L.elem[j+1] = L.elem[j]; //插入位置及之后的元素后移
L.elem[i-1] = e; //将新元素 e 放入第 i 个位置
++L.length; //表长增1
return OK;
}
}
将线性表 L 中第 i 个元素删除
Status ListDelete_Sq(SqList &L, int i)
{
if( (i<1) || (i > L.length) )
{
return ERROR; // i 值不合法
}
for( j=i; j <= L.length-1; j++ )
{
L.elem[j-1] = L.elem[j]; //被删除元素之后的元素前移
}
--L.length; //表长减 1
return OK;
}
链式表示
存储结构定义
typedef struct Lnode
{
ElemType data; //数据域
struct LNode *next; //指针域
} LNode,*LinkList;
//*LinkList 为 Lnode 类型的指针
初始化
Struct InitList_L(LinkList &L)
{
L = new LNode;
L -> next = NULL;
return OK;
}
销毁
Status DestroyList_L(LinkList &L)
{
LinkList p;
while(L)
{
p = L;
L = L -> next;
delete p;
}
return OK;
}
清空
Status ClearList(LinkList & L)
{
// 将L重置为空表
LinkList p,q;
p = L-> next; //p指向第一个结点
while(p) //没到表尾
{
q = p -> next;
delete p;
p = q;
}
L -> next = NULL; //头结点指针域为空
return OK;
}
求表长
//返回L中数据元素个数
int ListLength_L(LinkList L)
{
LinkList p;
p = L -> next; //p指向第一个结点
i=0;
//遍历单链表,统计结点数
while(p)
{
i++;
p=p->next;
}
return i;
}
判断表是否为空
int ListEmpty(LinkList L)
{
//若L为空表,则返回1,否则返回0
if(L->next)
{
//非空
return 0;
}
else
{
return 1;
}
}
取值(根据位置i获取相应位置数据元素的内容)
//获取线性表L中的某个数据元素的内容
Status GetElem_L(LinkList L,int i,ElemType &e)
{
p = L -> next;
j = 1; //初始化
while( p && j < i )
{
//向后扫描,直到p指向第i个元素或p为空
p = p -> next;
++j;
}
if(!p || j>i)
{
//第i个元素不存在
return ERROR;
}
e = p -> data; //取第i个元素
return OK;
}//GetElem_L
在线性表L中查找值为e的数据元素
LNode *LocateELem_L (LinkList L,Elemtype e)
{
//返回L中值为e的数据元素的地址,查找失败返回NULL
p =L->next;
while( p && p->data != e)
{
p=p->next;
}
return p;
}
int LocateELem_L (LinkList L,Elemtype e)
{
//返回L中值为e的数据元素的位置序号,查找失败返回0
p = L->next;
j = 1;
while(p && p->data != e)
{
p = p->next;
j++;
}
if(p)
{
return j;
}
else
{
return 0;
}
}
在 L 中第 i 个元素之前插入数据元素e
Status ListInsert_L(LinkList &L,int i,ElemType e){
p=L;
j=0;
//寻找第i−1个结点
while( p && j < i−1 )
{
p = p->next;
++j;
}
//i大于表长 + 1或者小于1
if(!p||j>i−1)
{
return ERROR;
}
s = new LNode; //生成新结点s
s->data = e; //将结点s的数据域置为e
s->next = p->next; //将结点s插入L中
p->next = s;
return OK;
}//ListInsert_L
将线性表L中第i个数据元素删除
Status ListDelete_L(LinkList &L,int i,ElemType &e){
p=L;j=0;
while(p->next &&jnext; ++j;
}
if(!(p->next)||j>i-1) return ERROR; //删除位置不合理
q=p->next; //临时保存被删结点的地址以备释放
p->next=q->next; //改变删除结点前驱结点的指针域
e=q->data; //保存删除结点的数据域
delete q; //释放删除结点的空间
return OK;
}//ListDelete_L
单链表的建立(前插法)
void CreateList_F(LinkList &L,int n){
L=new LNode;
L->next=NULL; //先建立一个带头结点的单链表
for(i=n;i>0;--i){
p=new LNode; //生成新结点
cin>>p->data; //输入元素值
p->next=L->next;L->next=p; //插入到表头
}
}//CreateList_F
单链表的建立(尾插法)
void CreateList_L(LinkList &L,int n){
//正位序输入n个元素的值,建立带表头结点的单链表L
L=new LNode;
L->next=NULL;
r=L; //尾指针r指向头结点
for(i=0;i>p->data; //输入元素值
p->next=NULL; r->next=p; //插入到表尾
r=p; //r指向新的尾结点
}
}//CreateList_L
循环链表的合并
//假设 Ta、Tb 都是非空的单循环链表
LinkList Connect(LinkList Ta,LinkList Tb)
{
p = Ta -> next; // p 存表头结点
Ta->next = Tb->next->next; // Tb 表头连结 Ta 表尾
delete Tb->next; //释放 Tb 表头结点
Tb->next = p; //修改指针
return Tb;
}
双向链表
typedef struct DuLNode{
ElemType data;
struct DuLNode *prior;
struct DuLNode *next;
}DuLNode, *DuLinkList
双向链表的插入
Status ListInsert_DuL(DuLinkList &L,int i,ElemType e){
if(!(p=GetElemP_DuL(L,i))) return ERROR;
s=new DuLNode;
s->data=e;
s->prior=p->prior;
p->prior->next=s;
s->next=p;
p->prior=s;
return OK;
}
双向链表的删除
Status ListDelete_DuL(DuLinkList &L,int i,ElemType &e)
{
if(!(p=GetElemP_DuL(L,i))) return ERROR;
e=p->data;
p->prior->next=p->next;
p->next->prior=p->prior;
delete p;
return OK;
}
线性表的合并
void union(List &La, List Lb){
La_len=ListLength(La);
Lb_len=ListLength(Lb);
for(i=1;i<=Lb_len;i++){
GetElem(Lb,i,e);
if(!LocateElem(La,e))
ListInsert(&La,++La_len,e);
}
}
// O(ListLength(LB) x ListLength(LB))
有序的顺序表合并
void MergeList_Sq(SqList LA,SqList LB,SqList &LC){
pa=LA.elem; pb=LB.elem; //指针pa和pb的初值分别指向两个表的第一个元素
LC.length=LA.length+LB.length; //新表长度为待合并两表的长度之和
LC.elem=new ElemType[LC.length]; //为合并后的新表分配一个数组空间
pc=LC.elem; //指针pc指向新表的第一个元素
pa_last=LA.elem+LA.length-1; //指针pa_last指向LA表的最后一个元素
pb_last=LB.elem+LB.length-1; //指针pb_last指向LB表的最后一个元素
while(pa<=pa_last && pb<=pb_last){ //两个表都非空
if(*pa<=*pb) *pc++=*pa++; //依次“摘取”两表中值较小的结点
else *pc++=*pb++; } pa++; //LB表已到达表尾
while(pb<=pb_last) *pc+
while(pa<=pa_last) *pc++=*+=*pb++; //LA表已到达表尾
}//MergeList_Sq
//T(n)= O(ListLength(LB) + ListLength(LB))
//S(n)= O(n)
有序的链表合并
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){
pa=La->next; pb=Lb->next;
pc=Lc=La; //用La的头结点作为Lc的头结点
while(pa && pb){
if(pa->data<=pb->data){ pc->next=pa;pc=pa;pa=pa->next;}
else{pc->next=pb; pc=pb; pb=pb->next;}
pc->next=pa?pa:pb; //插入剩余段
delete Lb; //释放Lb的头结点}
}
}