anAlgoProbAday-linked_list_problems

本文深入探讨了多种链表操作算法,包括两数相加、链表克隆、删除节点、寻找交点、循环检测、排序插入、链表回文检测、交替节点反转等,详细解析了每种算法的实现原理及技巧。
  1. add_two_numbers_lists
    解释:2个链表相加计算数值,比如5+11 = 16,感觉没啥用。
  2. cloneListWithRandomPtr
    解释:链表中有一个随机指针,如何克隆这样的链表,主要分为2步,第1步把原来的链表通过插入新的链节的方法复制一倍,然后把加长的链表分离2个链表,实现克隆的目的。
    形象如下:
    List in format (Node data, Random Node data) :
    (1, 3)–>(2, 1)–>(3, 5)–>(4, 3)–>(5, 2)–>NULL
    List in format (Node data, Random Node data) :
    (1, 3)–>(1, 3)–>(2, 1)–>(2, 1)–>(3, 5)–>(3, 5)–>(4, 3)–>(4, 3)–>(5, 2)–>(5, 2)–>NULL
  3. deleteLinkedlist
    解释:就是按规则删除链表,暂无。
  4. deleteNode
    解释:常规操作,把指针指向下一个链表节点。然后删除当前的节点。
  5. findIntersectionPointOfLists
    解释:就是把一个链表的指针指向另一个指针,然后找到这两个指针重合的位置。一般比较容易想的是比较指针的地址,其实比较长度就可以了,只需要比较1次。
  6. floyedCycleDetection
    解释:使用经典的佛罗伊的循环查找算法,找到循环开始的位置,方法比喻:A以B的2倍速度先跑,那么A一定先进入循环,当A再次遇到B时,A比B多跑了一个循环,而如果这时候让A从原点以同B一样的速度开始走,B继续走,则A与B再次相遇的点就是循环的起点。可以编写算式验证。比如x1+x2 =a; x1+x2+l = 2a ,即得x1+x2 = l(l为一个循环的长度)
  7. insertInASortedLinkedList
    解释:不难理解,就是比较大小后重排列。这个功能是插入时即排列。有点像sortedarray。
  8. listDemo
    解释:List封装了链表,Vector封装了数组,List和Vector最主要的区别在于vector使用连续内存存储的,vector支持[]运算符,而List是以链表形式实现的,不支持[],Vector对于随机访问的速度很快,但是对于插入尤其是在头部插入元素速度很慢,在尾部插入速度很快。List对于随机访问速度慢得多,因为可能要遍历整个链表才能做到,但是对于插入就快的多,不需要拷贝和移动数据,只要改变指针的指向就可以了。另外对于新添加的元素,vector有一套算法,而List可以任意加入。
  9. listPallindrome
    解释:使用了与 floyedCycleDetection差不多的策略,就是先平分链表,然后反转链表,然后进行比较,如果有不同的data说明不是对称链表。
  10. merge_sort
    解释:并归排序,还没有完全吸收代码。 膜拜一下这个程序。实现了并归排序,里面最精华的部分就是moveNode,它的参数类型是* &,活了那么久第一次见(自己low),来看下代码,其他没什么就是并归排序十大经典排序算法(动图演示)
void moveNode( Node * & dstNode, Node * & srcNode )
{
  if (srcNode == nullptr) {
    return;
  }
  //srcNode的next赋值给nextNode
  Node * nextNode = srcNode->next;
  //把srcNode传入dummy,记住这里是dummy,下一步dstNode的地址和dummy就不一样了,因为这里传进来的参数是* &,既可以改变地址指向的值也可以改变地址
  dstNode->next = srcNode;
  //dstNode地址被改变
  dstNode = srcNode;
  //srcNode地址被改变,这里nextNode没有被delete,数量大了会不会有内存泄露啊!
  srcNode = nextNode;
}

这里*&的解释C++中*和&同时使用是什么意思?,其实这个&的作用就是引用,可以改变指针地址的值。

  1. nthToLastNode
    解释:查找倒数第几个节点的位置。读懂这个,实现的原理就不难了。
  2. printMiddleNode
    解释:没啥,就是一快一慢的策略。
  3. rearrange_list
    解释:没啥,如果有的话我觉得亮点在reverse函数,其实就是一步一步把头节点分离出来,然后反过来输出。
void reverse( Node * & head )
{
  Node * nextNode = nullptr;
  Node * newHead = nullptr;
  Node * curr = head;
  while( curr ) {
    nextNode = curr->next;
    curr->next = newHead;
    newHead = curr;
    curr = nextNode;
  }
  head = newHead;
}
  1. removeDuplicatesFromSortedList
    解释:当比较不相等时,把地址重新赋值到head-next中。
  2. reverseAlternateNodes
    解释:和merge_sort差不多。忘了*&的含义,还是我介绍的清楚。其他应该没有什么。
  3. reverseLinkedListlterAndRecurse
    解释:reverseIter比较好理解,reverseRecur使用嵌套的方式进行翻转,单步调试大致明白,不好理解,不过也没有什么就是实现了翻转。
  4. swapNodesWithoutSwappingData
    解释:通过交换节点实现,分别预处理出要交换节点的前后节点链表,然后经过一顿操作(待深入分析),实现节点交换。
#include "linked_list.h" linked_list_ptr LINKED_LIST_CREATE () { linked_list_ptr linked_list_ptr_H = NULL; if (NULL == (linked_list_ptr_H = (linked_list_ptr)malloc (sizeof (linked_list_node)))) { return linked_list_ptr_H; } memset (&(linked_list_ptr_H->data), 'H', sizeof (linked_list_ptr_H->data)); linked_list_ptr_H->next = NULL; return linked_list_ptr_H; } int LINKED_LIST_FREE (linked_list_ptr linked_list_ptr_H) { if (NULL == linked_list_ptr_H) { return -1; } int num = -1; linked_list_ptr linked_list_ptr_node = linked_list_ptr_H; while (NULL != (linked_list_ptr_node = linked_list_ptr_node->next)) { free (linked_list_ptr_H); num ++; linked_list_ptr_H = linked_list_ptr_node; } free (linked_list_ptr_H); num ++; return num; } int LINKED_LIST_COUNT (linked_list_ptr linked_list_ptr_H) { int num = -1; while (NULL != linked_list_ptr_H) { linked_list_ptr_H = linked_list_ptr_H->next; num ++; } return num; } int LINKED_LIST_INSERT (linked_list_ptr linked_list_ptr_H, data_t data, int pos) { if (NULL == linked_list_ptr_H) { return -1; } int num = 0; if (-1 == pos) { while (NULL != linked_list_ptr_H->next) { linked_list_ptr_H = linked_list_ptr_H->next; num ++; } if (NULL == (linked_list_ptr_H->next = (linked_list_ptr)malloc (sizeof (linked_list_node)))) { return -2; } linked_list_ptr_H = linked_list_ptr_H->next; linked_list_ptr_H->data = data; linked_list_ptr_H->next = NULL; } else { while (NULL != linked_list_ptr_H->next && 0 != pos --) { linked_list_ptr_H = linked_list_ptr_H->next; num ++; } if (NULL == linked_list_ptr_H->next) { if (NULL == (linked_list_ptr_H->next = (linked_list_ptr)malloc (sizeof (linked_list_node)))) { return -2; } linked_list_ptr_H = linked_list_ptr_H->next; linked_list_ptr_H->data = data; linked_list_ptr_H->next = NULL; } else { linked_list_ptr linked_list_ptr_node = linked_list_ptr_H->next; if (NULL == (linked_list_ptr_H->next = (linked_list_ptr)malloc (sizeof (linked_list_node)))) { return -2; } linked_list_ptr_H = linked_list_ptr_H->next; linked_list_ptr_H->data = data; linked_list_ptr_H->next = linked_list_ptr_node; } } return num; } int LINKED_LIST_DELETE (linked_list_ptr linked_list_ptr_H, int pos) { if (NULL == linked_list_ptr_H) { return -1; } if (NULL == linked_list_ptr_H->next) { return -2; } int num = 0; if (-1 == pos) { while (NULL != linked_list_ptr_H->next->next) { linked_list_ptr_H = linked_list_ptr_H->next; num ++; } free (linked_list_ptr_H->next); linked_list_ptr_H->next = NULL; } else { while (NULL != linked_list_ptr_H->next->next && 0 != pos --) { linked_list_ptr_H = linked_list_ptr_H->next; num ++; } if (NULL == linked_list_ptr_H->next->next) { free (linked_list_ptr_H->next); linked_list_ptr_H->next = NULL; } else { linked_list_ptr linked_list_ptr_node = linked_list_ptr_H->next->next; free (linked_list_ptr_H->next); linked_list_ptr_H->next = linked_list_ptr_node; } } return num; } int LINKED_LIST_PURGE (linked_list_ptr linked_list_ptr_H) { if (NULL == linked_list_ptr_H) { return -1; } if (NULL == linked_list_ptr_H->next) { return 0; } if (NULL == linked_list_ptr_H->next->next) { return 1; } int num = 2; linked_list_ptr linked_list_ptr_node1 = NULL, linked_list_ptr_node2 = NULL; while (NULL != (linked_list_ptr_H = linked_list_ptr_H->next)->next->next) { linked_list_ptr_node1 = linked_list_ptr_H; while (NULL != linked_list_ptr_node1->next->next) { if (linked_list_ptr_H->data == linked_list_ptr_node1->next->data) { linked_list_ptr_node2 = linked_list_ptr_node1->next->next; free (linked_list_ptr_node1->next); linked_list_ptr_node1->next = linked_list_ptr_node2; continue; } linked_list_ptr_node1 = linked_list_ptr_node1->next; } if (linked_list_ptr_H->data == linked_list_ptr_node1->next->data) { free (linked_list_ptr_node1->next); linked_list_ptr_node1->next =NULL; } num ++; } return num; } linked_list_ptr LINKED_LIST_LOCATE_NUM2ADD (linked_list_ptr linked_list_ptr_H, int pos) { if (NULL == linked_list_ptr_H) { return NULL; } if (NULL == linked_list_ptr_H->next) { return NULL; } if (-1 == pos) { while (NULL != (linked_list_ptr_H = linked_list_ptr_H->next)->next); } else { while (NULL != (linked_list_ptr_H = linked_list_ptr_H->next) && 0 != pos --); } return linked_list_ptr_H; } int LINKED_LIST_LOCATE_ADD2NUM (linked_list_ptr linked_list_ptr_H, linked_list_ptr linked_list_ptr_node) { if (NULL == linked_list_ptr_H) { return -1; } if (NULL == linked_list_ptr_node) { return -2; } if (linked_list_ptr_H == linked_list_ptr_node) { return -3; } if (NULL == linked_list_ptr_H->next) { return -4; } int num = 0; while (NULL != (linked_list_ptr_H = linked_list_ptr_H->next) && linked_list_ptr_node != linked_list_ptr_H) { num ++; } if (linked_list_ptr_H != linked_list_ptr_node) { return -5; } return num; } int LINKED_LIST_REVERSE (linked_list_ptr linked_list_ptr_H) { if (NULL == linked_list_ptr_H) { return -1; } if (NULL == linked_list_ptr_H->next) { return 0; } if (NULL == linked_list_ptr_H->next->next) { return 1; } int num = 2; linked_list_ptr linked_list_ptr_node1 = linked_list_ptr_H->next, linked_list_ptr_node2 = linked_list_ptr_H->next->next, linked_list_ptr_node3 = linked_list_ptr_H->next->next->next; linked_list_ptr_node1->next = NULL; while (NULL != linked_list_ptr_node3) { linked_list_ptr_node2->next = linked_list_ptr_node1; linked_list_ptr_node1 = linked_list_ptr_node2; linked_list_ptr_node2 = linked_list_ptr_node3; linked_list_ptr_node3 = linked_list_ptr_node3->next; num ++; } linked_list_ptr_node2->next = linked_list_ptr_node1; linked_list_ptr_H->next = linked_list_ptr_node2; return num; } int LINKED_LIST_BUBBLE_SORT_MIN (linked_list_ptr linked_list_ptr_H) { int num = -1; linked_list_ptr linked_list_ptr_node = linked_list_ptr_H; while (NULL != linked_list_ptr_node) { linked_list_ptr_node = linked_list_ptr_node->next; num ++; } if (2 > num) { return num; } linked_list_ptr linked_list_ptr_node1 = linked_list_ptr_H->next, linked_list_ptr_node2 = linked_list_ptr_H->next->next; for (int i = 0; i < num - 1; i ++) { for (int j = 0; j < num - 1 - i; j ++) { if (linked_list_ptr_node1->data > linked_list_ptr_node2->data) { linked_list_ptr_node1->data ^= linked_list_ptr_node2->data; linked_list_ptr_node2->data ^= linked_list_ptr_node1->data; linked_list_ptr_node1->data ^= linked_list_ptr_node2->data; } linked_list_ptr_node1 = linked_list_ptr_node2; linked_list_ptr_node2 = linked_list_ptr_node2->next; } linked_list_ptr_node1 = linked_list_ptr_H->next; linked_list_ptr_node2 = linked_list_ptr_H->next->next; } return num; } int LINKED_LIST_BUBBLE_SORT_MAX (linked_list_ptr linked_list_ptr_H) { int num = -1; linked_list_ptr linked_list_ptr_node = linked_list_ptr_H; while (NULL != linked_list_ptr_node) { linked_list_ptr_node = linked_list_ptr_node->next; num ++; } if (2 > num) { return num; } linked_list_ptr linked_list_ptr_node1 = linked_list_ptr_H->next, linked_list_ptr_node2 = linked_list_ptr_H->next->next; for (int i = 0; i < num - 1; i ++) { for (int j = 0; j < num - 1 - i; j ++) { if (linked_list_ptr_node1->data < linked_list_ptr_node2->data) { linked_list_ptr_node1->data ^= linked_list_ptr_node2->data; linked_list_ptr_node2->data ^= linked_list_ptr_node1->data; linked_list_ptr_node1->data ^= linked_list_ptr_node2->data; } linked_list_ptr_node1 = linked_list_ptr_node2; linked_list_ptr_node2 = linked_list_ptr_node2->next; } linked_list_ptr_node1 = linked_list_ptr_H->next; linked_list_ptr_node2 = linked_list_ptr_H->next->next; } return num; } int LINKED_LIST_PRINTF (linked_list_ptr linked_list_ptr_H) { if (NULL == linked_list_ptr_H) { return -1; } int num = 0; linked_list_ptr linked_list_ptr_node = linked_list_ptr_H; while (NULL != (linked_list_ptr_node = linked_list_ptr_node->next)) { printf ("%d ", linked_list_ptr_node->data); num ++; } if (NULL != linked_list_ptr_H->next) { putchar ('\n'); } return num; } 寻找这段代码的错误
最新发布
12-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可峰科技

生活不易

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值