课堂笔记:循环链表、双向链表、静态链表

循环链表:将单链表或者双链表的头尾结点链接起来,就是一个循环链表。从循环表中任一结点出发,都能访问到表中其他结点。
特点:1、首尾相接的链表。2、可以从任一节点出发,访问链表中的所有节点。3、判断循环链表中尾结点的特点:q->next==first
空表的构造:

template<class T>
CycleLinkList<T>:: CycleLinkList( )
{
     first=new Node<T>; 
     first->next=first;
}

尾插法构造循环链表:

template<class T>   
CycleLinkList<T>:: CycleLinkList(T a[ ], int n)
{
     first=new Node<T>;    
     Node<T> *r,*s;      
     r=first;  
     for(int i=0; i<n; i++)
     {
          s=new Node<T>;          
          s->data=a[i];           
          r->next=s;
          r=s;
     }
     r->next=first; 
}      

头插法构造循环链表:

template<class T>
CycleLinkList<T>:: CycleLinkList(T a[ ], int n,int k)
{
     first=new Node<T>; 
     first->next=first; 
     Node<T> *s; 
     for(int i=1; i<n; i++)
     {
          s=new Node<T>; 
          s->data=a[i]; 
          s->next=first->next;
          first->next=s;
     }
}

将非循环的单链表改造成循环的单链表:

p=first;
while(p->next)
{
     p=p->next;
}
p->next=first

双链表
单链表的主要不足之处是:link字段仅仅指向后继结点,不能有效地找到前驱。双链表弥补了上述不足之处,增加一个指向前驱的指针 。
双链表的结点结构:

template<class T>
struct  DNode
{
     T data; 
     DNode<T> *llink; 
     DNode<T> *rlink;
}; 

双链表的结构特点:
由于在双向链表中既有前向链又有后向链,寻找任一个结点的直接前驱结点与直接后继结点变得非常方便。设指针p指向双链表中某一结点,则有下式成立: p->llink->rlink = p = p->rlink->llink
双向链表P之后插入节点(p存在后继结点)

q->rlink=p->rlink; 
q->llink=p;
p->rlink=q;
q->rlink->llink=q; 

处理原则:先处理每个方向的远端指针,再处理近端指针。
双向链表P之后插入节点(p存在后继结点)

q->rlink=p->rlink;
p->rlink=q;
q->llink=p;
q->rlink->llink=q;

处理原则:先在正向链表上插入,再在逆向链表上插入。
在空表中插入一个结点(在表尾插入一个结点)

q->rlink=p->rlink;
p->rlink=q;
q->llink=p;
if(q->rlink)
    q->rlink->llink=q;

双向链表的删除操作

p->llink->rlink=p->rlink;
p->rlink->llink=p->llink;
delete(p);

删除表尾结点

p->llink->rlink=p->rlink;
if(p->rlink)
    p->rlink->llink=p->llink;
delete(p);

双向链表的构造-空表的构造

template<class T>
DoubleLink <T>::DoubleLink(){
    head=new Node<T>; 
    head->rlink=NULL; 
    head->llink=NULL; 
}

头插法

template<class T>
void DoubleLink<T>::Append(T data){
     Node<T> *s;
     s=new Node<T>;
     s->data=data;
     s->rlink=head->rlink;
     head->rlink=s;
     s->llink=head;
     if(s->rlink)
         s->rlink->llink=s;
     return;
}

遍历

template<class T>
void DoubleLink<T>::Display(){
    Node <T> *p;
    p=head->rlink;
    while(p){
        cout<<p->data<<"   ";
        p=p->rlink;
    }
    cout<<endl;
    return;
}

析构

template<class T>
DoubleLink<T>::~DoubleLink(){
    Node<T>  *p,*q;
    p=head;
    while(p)
    {
        q=p->rlink;
        delete p;
        p=q;
    }
}

静态链表
静态链表的必要性:某些程序设计语言不支持指针类型。
特点:用顺序存储结构(数组)模拟实现链表。
静态链表可以借助一维数组来描述:

#define  Maxsize= 链表可能达到的最大长度
template<class T>
structNode{
    ElemType data; 
    int  next;
}; 

优点:插入和删除时不需要移动元素,直接修改指针即可,因此效率较高。
缺点:静态链表是借助于数组实现的,因此,不能动态的修改数组的大小,跟静态数组一样不能按需进行存储空间的分配。

发布了48 篇原创文章 · 获赞 25 · 访问量 2453

猜你喜欢

转载自blog.csdn.net/qq_43628959/article/details/101719766