数据结构学习日记(四)

循环链表:是一种头尾相接的链表(即:表中最后一一个结点的指针域指向头结点,整个链表形成一个环)

 

注意:

由于循环链表中没有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的头结点

 

案列分析与实现:

一元多项式的运算:实现两个多项式加、减、乘运算

 

posted @ 2021-09-07 18:03  aaawfss  阅读(229)  评论(0)    收藏  举报