码迷,mamicode.com
首页 > 其他好文 > 详细

反转单链表并验证(详解)

时间:2016-05-11 10:59:21      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:

单链表优点:

  1. 可以动态增加和删除。
  2. 不需要定义初始大小。

点链表缺点:

  1. 不能随机访问。需要逐个遍历直到找到目标项。
  2. 用到动态内存分配和指针,代码复杂度提升,内存泄漏和内存段错误风险提升。
  3. 开销大较大,因为是动态分配内存。而且每项需要存储一个额外的指针。

定义单链表:

    ------------------------------              ------------------------------
    |              |             |            \ |              |             |
    |      val     |     next    |--------------|      val     |     next    |
    |              |             |            / |              |             |
    ------------------------------              ------------------------------
单链表的每一个节点包含两部分:数据val和指向下一个节点的指针next。
1 typedef struct list_node ListNode;
2 
3 struct list_node{
4     int val;
5     struct list_node* next;
6 };

初始化单链表:

关键在两个指针:newNode和curNode。

newNode是用来指向新建节点。而curNode则是指向链表尾节点。

如果head为NULL,那么head和curNode都将指向newNode。

如果head不为NULL,那么只需将尾节点的next指向newNode,即curNode->next=newNode;,同时需记录新链表的尾节点,即curNode=newNode;。

以此类推,直到数组的最后一个元素的值插入到链表的尾部。

 1 ListNode* InitLinkedList(ListNode* head, int* array, int size)
 2 {
 3     head = NULL;
 4     ListNode* newNode = NULL;
 5     ListNode* curNode = NULL;
 6     for (int i = 0; i < size; i++)
 7     {
 8         newNode = malloc(sizeof(ListNode));
 9         newNode->val = array[i];
10         newNode->next = NULL;
11 
12         if (head == NULL)
13         {
14             head = newNode;
15             curNode = newNode;
16         }
17         else
18         {
19             curNode->next = newNode;
20             curNode = newNode;
21         }
22     }
23 
24     return head;
25 }

打印单链表:

1 void PrintLinkedList(ListNode* head)
2 {
3     while (head != NULL)
4     {
5         printf("%d ", head->val);
6         head = head->next;
7     }
8     printf("\n");
9 }

反转单链表:

反转的关键在于借助于两个额外指针p和q。同时记录q的next节点。因为q的next节点需要指向p,如果不先记录q的next节点,链表会就此断开。

接下来就是p和q的逐步向前推进,直到q指向NULL,而此时p刚好是反转后的链表的头节点。 

 1 ListNode* ReverseLinkedList(ListNode* head)
 2 {
 3     ListNode* p = NULL;
 4     ListNode* q = head;
 5 
 6     while (q != NULL)
 7     {
 8         ListNode* nextq = q->next;
 9         q->next = p;
10         p = q;
11         q = nextq;
12     }
13 
14     return p;
15 }

主函数:

 1 int main(void)
 2 {
 3     ListNode* root = NULL;
 4     int numArray[] = { 1, 2, 3, 4, 5 };
 5 
 6     root = InitLinkedList(root, numArray, 5);
 7     printf("original linked list:\n");
 8     PrintLinkedList(root);
 9 
10     root = ReverseLinkedList(root);
11     printf("reversed linked list:\n");
12     PrintLinkedList(root);
13 
14     getchar();
15     return 0;
16 
17 }

结果截图:

技术分享

 

解题的要点在于有一个清晰的思路,然后就是将逻辑用代码来实现。

 

 

反转单链表并验证(详解)

标签:

原文地址:http://www.cnblogs.com/wuscier/p/5481010.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!