Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3752
  • 博文数量: 6
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 75
  • 用 户 组: 普通用户
  • 注册时间: 2014-12-31 14:08
文章分类

全部博文(6)

文章存档

2015年(4)

2014年(2)

我的朋友
最近访客

分类: C/C++

2015-01-13 10:54:55

1, 判断单链表有没有环
2, 单链表长度为N, 找到第N/2个节点

解决这种问题的思路都是使用两个不同步长的指针遍历链表:
问题1:如果步长长的指针遇到NULL,则肯定没有环,负责两个指针必定相遇,链表存在环。可以想象一下两个人在圆形跑道跑步,一个跑的慢,一个跑的快,同时出发,还是会再次相遇的。
问题2:可以同时用步长1和步长2的两个指针遍历链表,当步长2的指针到达链表尾的时候,步长1的指针正好在中间节点

代码:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. // single list
  4. struct _slist
  5. {
  6.     struct _slist *next;
  7.     void *data;
  8. };
  9. typedef struct _slist slist;

  10. // test whether there is a circle in the list
  11. // use two pointers of different steps
  12. // if there is a circle in the list, they will
  13. // be the same at some point
  14. int test_circle(slist *plist)
  15. {
  16.     slist *p1 = NULL;
  17.     slist *p2 = NULL;

  18.     if (plist == NULL)
  19.         return 0;

  20.     p1 = plist;
  21.     p2 = plist->next;
  22.     while ((p2 != NULL) && (p2 != p1))
  23.     {
  24.         p1 = p1->next;
  25.         p2 = p2->next;
  26.         if (p2 != NULL)
  27.             p2 = p2->next;
  28.     }

  29.     return ((p2 == NULL) ? 0 : 1);
  30. }

  31. // get the middle node of the list
  32. slist* get_middle1(slist *plist)
  33. {
  34.     slist *p1 = NULL;
  35.     slist *p2 = NULL;

  36.     if (plist == NULL)
  37.         return NULL;

  38.     p1 = plist;
  39.     p2 = plist->next;
  40.     while ((p2 != NULL) && (p2->next != NULL))
  41.     {
  42.         p1 = p1->next;
  43.         p2 = p2->next->next;
  44.     }

  45.     return p1;
  46. }

  47. // get the middle node of the list
  48. slist* get_middle2(slist *plist)
  49. {
  50.     slist *p1 = NULL;
  51.     slist *p2 = NULL;
  52.     int count;

  53.     if (plist == NULL)
  54.         return NULL;

  55.     count = 0;
  56.     p1 = plist;
  57.     p2 = plist->next;
  58.     while (p2 != NULL)
  59.     {
  60.         p2 = p2->next;
  61.         count++;
  62.         if ((count & 0x01) == 0)
  63.             p1 = p1->next;
  64.     }

  65.     return p1;
  66. }

  67. slist* create_list(int n)
  68. {
  69.     slist *head = NULL;
  70.     slist *tail = NULL;
  71.     slist *tmp = NULL;
  72.     int i = 0;

  73.     for (i = 0; i < n; i++)
  74.     {
  75.         tmp = (slist*)malloc(sizeof(slist));
  76.         if (tmp != NULL)
  77.         {
  78.             tmp->next = NULL;
  79.             tmp->data = (void *)i;

  80.             if (head == NULL)
  81.             {
  82.                 head = tmp;
  83.             }
  84.             if (tail != NULL)
  85.             {
  86.                 tail->next = tmp;
  87.             }
  88.             tail = tmp;
  89.         }
  90.     }

  91.     return head;
  92. }

  93. void destroy_list(slist *plist)
  94. {
  95.     slist *p = plist;
  96.     slist *tmp = NULL;
  97.     while (p != NULL)
  98.     {
  99.         tmp = p;
  100.         p = p->next;
  101.         free(tmp);
  102.     }
  103. }

  104. void print_list(slist *plist)
  105. {
  106.     slist *p = plist;
  107.     while (p != NULL)
  108.     {
  109.         printf("%x ", p->data);
  110.         p = p->next;
  111.     }
  112. }

  113. int main(int argc, char* argv[])
  114. {
  115.     slist *plist1 = NULL;
  116.     slist *plist2 = NULL;
  117.     slist *tmp = NULL;
  118.     slist *tail = NULL;
  119.     int i;

  120.     plist1 = create_list(5);
  121.     plist2 = create_list(10);

  122.     printf("list1: ");
  123.     print_list(plist1);
  124.     printf("\n");
  125.     printf("get_middle1: %d\n", (int)(get_middle1(plist1)->data));
  126.     printf("get_middle2: %d\n", (int)(get_middle2(plist1)->data));

  127.     printf("list2: ");
  128.     print_list(plist2);
  129.     printf("\n");
  130.     printf("get_middle1: %d\n", (int)(get_middle1(plist2)->data));
  131.     printf("get_middle2: %d\n", (int)(get_middle2(plist2)->data));

  132.     tmp = plist2->next->next;
  133.     tail = plist2;
  134.     while (tail->next != NULL)
  135.     {
  136.         tail = tail->next;
  137.     }
  138.     tail->next = tmp;

  139.     printf("test_circle: list1, %d\n", test_circle(plist1));
  140.     printf("test_circle: list2, %d\n", test_circle(plist2));

  141.     tail->next = NULL;
  142.     destroy_list(plist1);
  143.     destroy_list(plist2);

  144.     return 0;
  145. }
输出:
list1: 0 1 2 3 4
get_middle1: 2
get_middle2: 2
list2: 0 1 2 3 4 5 6 7 8 9
get_middle1: 4
get_middle2: 4
test_circle: list1, 0
test_circle: list2, 1

阅读(62) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~