2.1线性结构特点 1、一个首一个尾 2、除首尾外其他结点只有一个直接前驱和一个直接后继。 线性结构包括线性表、堆栈、队列、字符串、数组,最常用的是线性表。 2.2案例引入 一元多项式的运算 稀疏多项式的运算 线性表P=((p1,e1),(p2,e2),…,(pm,em)) 2.3线性表的存储类型与操作定义 线性表的存储结构
2.4线性表顺序存储的实现 用一组地址连续的存储单元依次存储线性表的元素,可通过数组V[n]来实现。 线性表的重要的基本操作
初始化、销毁、清空、求长,判断是否为空 初始化线性表L 方法一 Status InitList(SqList&L){ //构造一个空的顺序表L
L.elem=new ElemType[MAXSIZE]; //为顺序表分配空间
if(!L.elem) exit(OVERFLOW); //分配失败
L.length=0; //空表长度为0;
return OK;
} 方法二 Status InitList_Sq(SqList *L){
L->elem = new ElemType[MAXSIZE];
if(!L->elem) exit(OVERFLOW);
L->length=0;
return OK;
} 删除线性表 void DestroyList(SqList &L){
if (L.elem)delete[ ]L.elem;
} 清空线性表L void ClearList(SqList)
{
L.length=0;
} 求线性表的长度 int GetLength(SqList L)
{
return (L.length);
} 判断线性表L是否为空 int IsEmpty(SqList L)
{
if (L.length==0)
return 1;
else
return 0;
}
获取线性表L中的某个数据元素的内容 int GetElem(SqList L,int I,ElemType &e)
{
if (i<1 || i>L.length) return ERROR;
e = L.elem[i-1];
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;
}
算法思路 1、判断插入位置i是否合法 2、判断顺序表的存储空间是否已满 3、将第n至第i位的元素依次向后移动一个位置,空出第i个位置 4、将要插入的新元素e放入第i个位置 5、表长加1,插入成功返回ok Status ListInsert_Sq(SqList &L,int i,ElemType e){
if (i< || i>L.length+1) return ERROR; //判断I的合法性
if(L.length==MAXSIZE) return ERRORS; //判断顺序表的存储空间是否已满
for(j=L.length-1;j>=i-1;j—)
L.elem[j+i]=L.elem[j];
L.elem[i-1]=e;
++L.length;
return OK;
}
Status ListDelete_Sq(SqList &L,int i){
if ((i<1)||(i<L.length)) return ERROR;
for(j=I;j<=L.length-1;j++)
L.elem[j-1]=L.elem[j]; //被删除元素之后的元素前移
—L.length;
return OK;
} 2.5线性表链式存储的实现 在链表中设置头结点的好处 1、便于首结点的处理 首元结点的地址保存在头结点的指针域中,所以在链表的第一个位置上的操作与其他位置的一致,无须进行特殊处理。 2、便于空表与非空表的统一处理 无论链表是否为空,头指针都是指向头结点的非空指针,因此空表和非空表的处理也就统一了。 单链表存储结构定义 typedef struct LNode{
ElemType data;
struct LNode *next;
} LNode,*LinkList; 单链表 (1)初始化 1、生成新结点作头结点,用头结点L指向头结点 2、头结点的指针域置空 Status InitList_L(LinkList&L){
L=new LNode;
L->next=NULL;
return OK;
} 销毁 Status DestroyList_L(LinkList&L){
LinkList p;
while(L) //while(L!=NULL)
{
p=L;
L=L->next;
delete p;
}
return 0;
} 清空 Status ClearList(LinkList &L){
LinkList p,q;
p=L->next;
while(p)
{
q=p->next;
delete p;
p=q;
}
L->next=NULL;
return OK;
} 求表长 int ListLength_L(LinkList L)
{
LinkList p;
p=L->next;
i=0;
while(p){
i++;
p=p->next;
}
return i;
} 判断表是否为空 int ListEmpty(LinkList L)
{
if(L->next)
return 0;
else
return 1;
} 取值 Status GetElem_L(LinkList L,int I,ElemType &e){
p=L->next ; j=1; //初始化
while(p&&j<i){
p=p->next; ++j;
}
if(!p || j>I ) return ERROR; //第i个元素不存在
e=p-data; //取第i个元素
return OK;
}
查找 LNode *LocateELem_L(LinkList L, Elemtype e) //定义上带*号
{
p=L->next;
while(p&&p->data!=e)
p=p->next;
return p; //返回的是数据元素的地址
}
//返回地址序号 int LocateELem_L(LinkList L,Elemtype e){
p=L->next; j=1;
while(p&&p->data!=e)
{
p=p->next; j++;
}
if(p) return j;
else return 0;
} 插入 //在第i个元素之前插入 Status ListInsert_L(LinkList &L,int i,ElemType){
p=L; j=0;
while(p&&j<i-1){p=p->next; ++j}
if(!p || j>i-1) return ERROR;
s=new LNode;
s->date=e;
s->next=p->next;
p-next=s;
return OK:
} 删除 Status ListDelete_L(LinkList &L,int i;ElemType &e){
p=L;j=0;
while(p->next &&j<i-1){
p=p->next; ++j;
}
if(!(p->next) || j>j-1) return ERROR;//
q=p->next;
p->next=q->next;
e=q->data;
delete q;
return OK;
} 单链表的建立(前插法) void CreateList_F(LinkList&L,int n){
L=next LNode
L->next=NULL; //先建立一个带头结点的单链表
for(I=n; I>0; —i){
p=new LNode; //生成新结点
cin>>p->data; //输入元素值
p->next=L->next; L-next=p; //插入到表头
}
} 单链表的建立(尾插法) void CreateList_L(LinkList &L, int n){
L=new LNode;
L->next=NULL;
r=L;
for(I=0;i<n;i++){
p=new LNode; //生成新结点
cin>>p->data; //输入元素值
P->next=NULL; r->next=p; //插入到表尾
r=p; //指向新的尾结点
}
}
双向链表 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))) rerutrn ERROR;
s=new DuLNode;
s->data=e;
s->prior=p->prior;
p->prior->next=s;
s->next=p;
p->prior=s;
return OK;
} 2.6顺序表和链表的区别 查找元素顺序表的时间复杂度O(1),链表的时间复杂度为O(n) 插入删除顺序表的 时间复杂度为O(n),链表的时间复杂度为O(1) 2.7 线性表的合并 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);
}
} 有序表的合并 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);
}
} 有序链表的合并(允许有重复) void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){
pa=La->next; pb=Lb->next;
pc=Lc=La;
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;
deleta Lb;
}
} |