数据结构第二次笔记

  •  

    ​一、双链表

    1.如果希望快速​确定单链表中任一结点的前驱结点,可以在单链表中再设置一个指向其前驱结点的指针域,这样就形成了双链表。

    2.在双链表中,每个结点在存储数据元素的同时,还存储了其前驱元素和后继元素所在结点的地址信息。

    双链表的结点定义结构:

    template<class T>

    struct​ Node

    {

    T data;

    Node<T>*prior,*next;

    }

    3.插入操作

    在结点p的后面插入一个新节点s,需要修改4个指针。

    1.  s->prior​=p;

    2.  s->next=p->next;

    3.  p->next->prior=s;

    4.  p->next=s;​

    第四步指针的修改要在2和3步的指针修改完成后才能进行。

    4.删除操作

    ​1.  (p->prior)->next=p->next;

    2.  (p->next)->prior=p->prior;

    这两个语句可以颠倒。执行删除操作后,还要将结点p所占的存储空间释放。​

    二、​循环链表

    ​1.将单链表或者双链表的头尾结点链接起来,就是一个循环链表。不增加额外存储花销,却给不少操作带来了方便

    从循环表中任一结点出发,都能访问到表中其他结点。

    2.​特点:首尾相接的链表。

    可以从任一节点出发,访问链表中的所有节点。

    判断循环链表中尾结点的特点: q->next==first

    ​3.空表的构造

    template <class T>

     

    CycleLinkList<T>:: CycleLinkList( )

     

    {

    first=new Node<T>;

    first->next=first;

    }

    4.尾插法构造循环链表

    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;

    }

    5.头插法构造循环链表

    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;

    }

    }

     

    三、循环链表解决​约瑟夫环问题

    ​#include<iostream>

    using namespace std;

    struct Node

     

    { int data;

    Node *pNext;};

     

    int main()

    {

        int n, k, m, i;

    struct Node *p, *q, *head;

        

    cin >> n>>k>>m;

        

    if(m==1) 

    { int left; 

    left=k-1;

    if(left==0) 

    left=n; 

    cout<<left; 

    return 0; } 

       

    first = (Node*)new Node;         

       

    p = first;

    first->data=1;

       

    for (i = 2; i <= n; i++)

    {q=new Node;  

    q->data=i;

    p->next =q;

    p=p->pNext;

       

    }

       

    p->pNext = first;                        

       

    p = first;

       

    for(i=1;i<=k-1;i++)

            

    p=p->pNext;

    ​while (p != p->pNext)

    {

    for (i = 1; i<m - 1; i++)    

    {

    p = p->pNext;

    }       

    q = p->pNext;

    p->pNext=q->pNext; 

    delete q;

    p=p->pNext;

    }

    cout << p->data <<endl; 

    return 0;

     

    }

    ​四、有序链表合并

    ​emplate <class T>

    void  merge(LinkList<T> LA, LinkList<T> LB)

    {

        Node <T> *pa,*pb,*pc;

     

    pa=LA.first;

    pb=LB.first;

    pc=LA.first;

    pa=pa->next;

    pb=pb->next;

    while(pa&&pb)

    {

               

    if (pa->data>pb->data)

    { pc->next=pb;

    pc=pb;

    pb=pb->next;}

    else

     

    { pc->next=pa;

    pc=pa;

    pa=pa->next; }

    }

    if (pa) pc->next=pa;

    else

    pc->next=pb;

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值