链表

一、单向链表

 假设单向链表的节点定义如下:

1 struct ListNode {
2     int val;
3     ListNode *next;
4 };


1、往链表结尾添加一个节点:

 1 void AddToTail(ListNode **pHead, int value) {
 2     ListNode *pNew = new ListNode();
 3     pNew->val = value;
 4     pNew->next = NULL;
 5     
 6     if (*pHead == NULL) {
 7         *pHead = pNew;
 8     } else {
 9         ListNode *pNode = *pHead;
10         while (pNode->next != NULL) {
11             pNode = pNode->next;
12         }
13         pNode->next = pNew;
14     }
15 }

关键在于函数的第一个传入参数是一个指向指针的指针。当我们往空链表插入节点时,新插入的节点就是链表的头指针,由于此时会改动头指针,因此必须把pHead参数设置为指向指针的指针,否则出了这个函数pHead仍然是一个空指针。

 

如下面的代码:

 1 void AddToTail(ListNode* pHead, int value) {
 2     ListNode *pNew = new ListNode();
 3     pNew->val = value;
 4     pNew->next = NULL;
 5     
 6     if (pHead == NULL) {
 7         pHead = pNew;
 8     } else {
 9         ListNode *pNode = pHead;
10         while (pNode->next != NULL) {
11             pNode = pNode->next;
12         }
13         pNode->next = pNew;
14     }
15 }

如果一开始是一个空链表,经过插入新节点后,虽然这个函数内部pHead指向新的节点,但是返回的链表,pHead还是空指针。

除了用指向指针的指针,还可以用引用(&):

 1 void AddToTail(ListNode* &pHead, int value) {
 2     ListNode *pNew = new ListNode();
 3     pNew->val = value;
 4     pNew->next = NULL;
 5     
 6     if (pHead == NULL) {
 7         pHead = pNew;
 8     } else {
 9         ListNode *pNode = pHead;
10         while (pNode->next != NULL) {
11             pNode = pNode->next;
12         }
13         pNode->next = pNew;
14     }
15 }


2、在链表中找到第一个含有某值的节点,并删除该节点。

 

 1 void RemoveNode(ListNode* &pHead, int value) {
 2     if (pHead == nullptr) {
 3         return;
 4     }
 5     ListNode *pToBeDelete = nullptr;
 6     if (pHead->val == value) {
 7         pToBeDelete = pHead;
 8         pHead = pHead->next;
 9     } else {
10         ListNode *pNode = pHead;
11         while (pNode->next != nullptr && pNode->next->val != value) {
12             pNode = pNode->next;
13         }
14         if (pNode->next != nullptr && pNode->next->val == value) {
15             pToBeDelete = pNode->next;
16             pNode->next = pNode->next->next;
17         }
18     }
19     if (pToBeDelete != nullptr) {
20         delete pToBeDelete; //只删除了pToBeDelete指针指向的对象,释放了它的堆内存空间,指针还是指向原来的内存 
21         pToBeDelete = nullptr; //变成空指针,否则由于上面的delete操作,会使它变成野指针。 
22     }
23 }

 

posted @ 2019-07-19 11:47  琴影  阅读(149)  评论(0编辑  收藏  举报