zoukankan      html  css  js  c++  java
  • 链表合并

    链表合并先,将两个链表排序,在合并的时候引入一个内存泄露的问题,之后会继续讨论。

    #include <ctime>
    #include <cstdlib>
    #include <iostream>
    #include <cstdio>

    using namespace std;

    #define NN
    #define RANGE 100
    #define NUM 10

    struct node
    {
     int value;
     node * next;
     node(int v = -1, node *nxt = NULL) : value(v),next(nxt){}
    };

    node * make_link();
    void display(node *);
    void sort(node *);
    node * merge(node *,node *);
    void mem_realse(node *);

    int get_rand()
    {
        return rand() % RANGE;
    }

    node *mcur_;

    int main()
    {

     node* head1 = make_link();
     display(head1);
     sort(head1);

     node* head2 = make_link();
     display(head2);
     sort(head2);

        node *head = merge(head1,head2);

     display(head);

     mem_realse(head);

     delete mcur_;


     return 0;
    }

    node * make_link()
    {

     node *head = new node();//没有表头
     node *cur = head;
     srand( time(NULL) );
     for(int i= 0; i < NUM - 1; i++)
     {
      cur->value = rand() % RANGE;
      cur->next = new node();
      cur = cur->next;
      cur->next = NULL;
     }
     cur->value = rand() % RANGE;//最后一个数

     return head;
    }
    void display(node *head)
    {
     node *cur = head;
     int nodeNum = 0;
     while(cur)
     {
      cout << cur->value << " " ;
      nodeNum++;
      cur = cur->next;
     }
     cout << endl;
    #ifdef NN
     cout << nodeNum<<endl;
    #endif
    }

    void sort(node *head)
    {

     node *cur = head;

     while(cur)                 //两重循环(每重循环维护一个当前指针),每次从链表中找出一个值最小的结点,
     {                         //保存其指针,然后与当前第一个进行值互换
      node *min = cur;
      node *cur2 = cur->next;
      while(cur2)
      {
       if(cur2->value < min->value)
       {
        min = cur2;
       }
       cur2 = cur2->next;
      }
      int tem = cur->value;
      cur->value = min->value;
      min->value = tem;
      cur = cur->next;
     }


    }
    node * merge(node *h1,node *h2)   //O(1)的,需要一个辅助的结点,两个链表需要已经进行了排序
    {                                 // 没次从两个链表中选出一个合适的来作为新链表的下一个结
     node *mcur = new node();      // 辅助结点,不能仅仅是一个指针,next域需要发挥作用
     mcur_ = mcur;
     ///其实这个mcur是没有存储结点数据的,合并完之后造成了mcur不会指向一开始分配的这块内存区域
     ///造成这块区域的内存无法回收,所以使用了mcur_ 这个全局变量来保存该指针,最后来释放这块区域
     ///我以开始就意识到了,但是没有办法论证,接下来会有博客文章会借助Visual Studio的运行库函数来分析内存泄露问题
     node *cur1 = h1 , *cur2 = h2; //辅助结点始终指向“新链表”的当前结点,也可以说是最近一个加入该链表的结点
     while(cur1 && cur2)
     {
      if(cur1->value < cur2->value)
      {
       mcur->next = cur1;
       mcur = mcur->next;//mcur指向当前的cur1
       cur1 = cur1->next;//cur1已经处理,指向下一个

      }
      else
      {
       mcur->next = cur2;
       mcur = mcur->next;
       cur2 = cur2->next;
      }
     }
     if(cur1)
     {
      mcur->next = cur1;
     }else
     {
      mcur->next = cur2;
     }

     //cout << "mcur->value: "<< mcur->value <<endl;


     return h1->value < h2->value ? h1 : h2;//merge 函数其实只是将两个链表的指针进行了重新组织,并没有使用新的区域
    }

    void mem_realse(node *h)
    {
     node *p = h;
     int count = 0;
     while(p)
     {
      h = p -> next;
      delete p;
      count++;
      p = h;
     }
     cout << "realse " << count << " node " <<endl;
    }

    很奇怪,在生成随机数的时候,两次make_link生成的数据时相同的,我已经加了srand(time(NULL))了。。。。

  • 相关阅读:
    友盟上报 IOS
    UTF8编码
    Hill加密算法
    Base64编码
    Logistic Regression 算法向量化实现及心得
    152. Maximum Product Subarray(中等, 神奇的 swap)
    216. Combination Sum III(medium, backtrack, 本类问题做的最快的一次)
    77. Combinations(medium, backtrack, 重要, 弄了1小时)
    47. Permutations II(medium, backtrack, 重要, 条件较难思考)
    3.5 find() 判断是否存在某元素
  • 原文地址:https://www.cnblogs.com/zhuyp1015/p/2508412.html
Copyright © 2011-2022 走看看