zoukankan      html  css  js  c++  java
  • 灵活利用单链表,顺带一提可持久化链表。

    #include<stdio.h>
    
    /**                                   单链表                                                          **/
    /*      利用指针可以为直接映射到改变上 且后续的地址传递比较方便,永远不要对表头做操作。只赋值。        */
    struct Node
    {
        int val;
        Node * next;
    };
    Node * Head,Last; 
    void CreatList_L(int n)
    {
            Node *p,*q;
            Head = new Node();
            Head->next = NULL;
            p = Head;
            while(n--)
            {
                q = new Node();
                scanf("%d",&q->val);
                q->next = p->next;
                p->next = q;
            }
    }
    void CreatList_LO(int n)
    {    
        Node *p,*q;
        Head = new Node();
        Head ->next = NULL;
        p = Head;
        while(n--)
        {
            q = new Node();
            scanf("%d",&q->val);
            q -> next = NULL; 
            //这个是需要注意的。一开始 q->next 初始化出来之后的值是随机的。并非NULL.而输出时候直接while(p) 即利用NULL==0
            p->next = q;
            p = p->next;
        }
    }
    /*
    对于insert 我们只考虑insert 0 位置才是最有效率的 那么要实现添加为O(1)就必须在建表的时候。
    对于逆建表。 insert 相当于在一个序列的尾巴插入 并且你可以即时处理这个尾部
    对于顺序建表。insert 相当于在一个序列的头部插入 并且你可以即时处理这个头部
    */
    void OutPut()
    {
        Node *p;
        p = Head->next;
        while(p)
        {
            printf("%d",p->val);
            p = p->next;
        }
    }
    
    int main()
    {
    /*  int *L;
        L = new int();
        int n,i;
        while(scanf("%d",&n)!=EOF)
        {
            for(i=0;i<n;i++)
            {
                scanf("%d",&L[i]);
            }
            for(i=0;i<n;i++)
            {
                printf("%d",L[i]);
            }
        }
        顺序表 q = L+L.lenth-1 就能指向顺序表的最底端
    */
    
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            CreatList_LO(n);
            OutPut();
        }
    }
    单链表的建立

    对于可持久化链表:

      思考一个这样的问题。对于可持久化链表(确切地说应该是可持久化数据结构)。可持久化体现在能够恢复到旧版本。可以联想浏览器的历史痕迹。即对链表的每一步操作能做一个新版本来保存起来。

    http://www.cnblogs.com/tedzhao/archive/2008/11/12/1332112.html

    这里有更加全面的解释。感谢这位作者的辛勤劳动。

    具体实现:

      我们需要用一个数组存储各个版本的头指针。根据上面链接的那个博文可以知道插入中间的时候。前面的所有节点都要复制下来。这是必须的。因为单链表是从头指针开始的。如果不复制。头指针就只有一个。明显不能符合版本分开。假如理想状态下。我们的每次插入如果不是插入。而是添加(添加也是插入)。添加到头位置。(添加到尾部就是恰恰最坏情况了)。那我们的可持久化链表是极其有效率的。

    这里有一个题恰恰是利用了这个特点。

    URAL 1992 CVS

    模拟题

    分析时间 基本上可以知道 要求我们的每一步操作是在O(1)的级别。

    这个题目要支持维护最后一个元素。(不管是学习列表还是记忆列表)。

    那么我们应该使用逆建表。这里有一个问题就是数据是实时的。

    那我们只要把模仿着逆建表慢慢添加入元素即可

    用一个数组存储表头。维护count 每一次操作后加1表示有新的版本。

    code 后续补上。

  • 相关阅读:
    在Vue-cli3.x中引入element-ui的新方式
    通过JS屏蔽鼠标右键
    java异常有效实践
    设计之禅——迭代器模式
    设计之禅——状态模式
    设计之禅——外观模式
    设计之禅——适配器模式
    设计之禅——我只要结果(命令模式)
    设计之禅——装饰者模式详解(与代理模式的区别以及与其他模式的组合)
    设计之禅——生成器模式
  • 原文地址:https://www.cnblogs.com/Milkor/p/4387573.html
Copyright © 2011-2022 走看看