数据结构学习日记(四)
循环链表:是一种头尾相接的链表(即:表中最后一一个结点的指针域指向头结点,整个链表形成一个环)
注意:
由于循环链表中没有NULL指针,故涉及遍历操作时,其终止条件就不再像非循环链表那样判断p或p- >next是否为空,而是判断它们是否等于头指针。
循环条件:
对于单链表:
p!=NULL;
p->next!=NULL;
对于单循环链表:
p!=L;
p->next!=L;

带尾指针循环链表的合并
算法描述:
LinkList Connect(LinkList Ta,LinkList Tb){//假设Ta、Tb都是非空的单循环链表
p = Ta->next; //①p存表头结点
Ta->next = Tb->next->next; //②Tb表头连结Ta表尾
delete Tb->next; //3释放Tb表头结点”
Tb->next = p; //④修改指针
return Tb;
}
双向链表:在单链表的每个结点里再增加一个指向其直接前驱的指针域prior,这样链表中就形成了有两个方向不同的链,故称为双向链表。

双向链表的结构可定义如下:
typedef struct DuLNode{
Elemtype data;
struct DuLNode *prioi,*next;
}DuLNode,*DuLinkList;
双向链表结构的对称性(设指针p指向某一结点) :
p->prior->next = p = p->next->prior
双向链表的插入

算法描述:
void Listlnsert_Dul(DuLinkList &L,int i,ElemType){//在带头结点的双向循环链表L中第i个位置之前插入元素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;
}//Listinsert_DuL
双向链表的删除

算法描述:
void ListDelete_DuL(DuLink&L,int i,ElemType &e){//删除带头结点的双向循环链表L的第i个元素,并用e返回
if(!(p=GetElemP_DuL(L,i))) return ERROR;
e = p->data;
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);
return OK;
}
线性表的合并:
问题描述:
假设利用两个线性表La和Lb分别表示两个集合A和B,现要求一个新的集合A=AUB
La=(7, 5,3,11) Lb=(2, 6,3) - > La=(7,5,3, 11,2, 6)
算法步骤:
依次取出Lb中的每个元素,执行以下操作:
1.在La中查找该元素
2.如果找不到,则将其插入La的最后
算法实现:
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))
Listlnsert(&La,++La_len,e);
}
}
有序表的合并
■已知线性表La和L中的数据元素按值非递减有序排列,现要求将La和Lb归并为一个新的线性表Lc,且Lc中的数据元素仍按值非递减有序排列。
La=(1,7,8) Lb=(2, 4, 6,8,10,11)- > Lc=(1,2,4,6, 7 ,8, 8,10, 11)
算法步骤:
(1)创建一一个空表Lc
(2)依次从La或Lb中"摘取.". 元素值较小的结点插入到Lc表的最后,直至其中一个表变空为止
(3)继续将La或Lb其中一个表的剩余结点插入在Lc表的最后
有序表合并-------用顺序表实现:
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指向L A表的最后-个元素
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++;
}
whlie(pa<=pa_last) *pc++=*pa++; //LB表已到达表尾,将LA中剩余元素加入LC
whlie(pb<=pb_last) *pc++=*pb++; //LA表已到达表尾,将LB中剩余元素加入LC
}
有序表合并用链表实现
void MergeList_Sq(SqList LA,SqList LB,SqList &LC){
pa = La->next;
pb = Lb->next;
pc=Lc=La; //用La的头结点作为Lc的头结点
while(pa && pb){
if(pa->data<=pb->data){
pc->next=pa;
pa=pa;
pa=pa->next;
else{
pc->next=pb;
pc=pb;
pb=pb->next;
}
pc->next=pa?pa:pb;//插入剩余段
delete Lb;//释放Lb的头结点
案列分析与实现:
一元多项式的运算:实现两个多项式加、减、乘运算


浙公网安备 33010602011771号