博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
链表合并
阅读量:6184 次
发布时间:2019-06-21

本文共 2464 字,大约阅读时间需要 8 分钟。

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

#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))了。。。。

转载地址:http://dxsda.baihongyu.com/

你可能感兴趣的文章
深入实践Spring Boot1.6 小结
查看>>
为什么会"well-known file is not secure" ?
查看>>
ThinkPHP隐藏index.php的方法汇总【IIS/Apache/Nginx】
查看>>
<转>进程与线程的一个简单解释
查看>>
typescript 学习教程 (1)
查看>>
Hadoop 解除 "Name node is in safe mode"
查看>>
正则表达式
查看>>
字符串处理的练习~
查看>>
一名网工对Linux运维的一次经历
查看>>
jdbc中如何使用classloader
查看>>
在Struts2中方便获得Spring中的Bean方法
查看>>
「ThinkPHP开发者周刊」第2期
查看>>
思达报表工具Style Report基础教程—交叉表
查看>>
H3C笔试题目
查看>>
成为一名优秀的Web前端开发者
查看>>
mybatis 学习笔记
查看>>
Spring Boot AOP
查看>>
Mysql导出sql语句的方法及可能遇到的mysqldump: command not found
查看>>
网站建设PHP mysql 事务处理实例
查看>>
家人重病什么心情都没了
查看>>