【剑指offer】面试题13、在 O(1)时间上删除链表结点
2015-06-18 18:33
363 查看
题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。链表结点与函数的定义如下: typedef struct Node { int m_nValue; struct Node *m_pNext; }ListNode, *pListNode; void DeleteNode(ListNode **pHead, ListNode *pToBeDeleted);
在单链表中删除一个结点,最常用的做法莫过于从链表的头结点开始,顺序遍历查找并找到要删除的结点,然后再进行删除操作。
比如在下图(a)所示的链表中,我们想要删除结点 i,我们就可以从头结点开始遍历该链表,遍历到 h 结点时,会发现 h 的下一个结点 i 就是我们所要删除的结点。这样我们可以把 h 的 m_pNext指向 i 的下个结点 j。指针调整之后我们就可以安全删除结点 i 并保证链表没有断开。
这种顺序查找的时间复杂度为 O(n)。
// deleteNode.c #include "stdio.h" #include "stdlib.h" #define N 10 typedef struct Node { int m_nValue; struct Node *m_pNext; }ListNode, *pListNode; void deleteNode(ListNode **pHead, ListNode *pToBeDeleted); // 获得要删除结点 ListNode *getNodeIndex(ListNode *pHead, int index); void createList(ListNode **pHead, int len) { ListNode *pTail = NULL; while(len--) { ListNode *pNew = (ListNode*)malloc(sizeof(ListNode)); pNew->m_nValue = rand()%100; pNew->m_pNext = NULL; if(*pHead == NULL) { *pHead = pNew; pTail = pNew; } else { pTail->m_pNext = pNew; pTail = pNew; } } } void printList(ListNode *pHead) { while(pHead != NULL) { printf("%3d ", pHead->m_nValue); pHead = pHead->m_pNext; } printf("\n"); } void deleteNode(ListNode **pHead, ListNode *pToBeDeleted) { if(!pHead || !pToBeDeleted) return; // 链表有多个结点,并且删除的不是尾结点 if(pToBeDeleted->m_pNext != NULL) { ListNode *pNext = pToBeDeleted->m_pNext; pToBeDeleted->m_nValue = pNext->m_nValue; pToBeDeleted->m_pNext = pNext->m_pNext; free(pNext); pNext = NULL; } // 还剩两种情况:要么链表只有一个结点,要么删除的是尾结点(含有多个结点) else if(*pHead == pToBeDeleted)// 链表只有一个结点 { free(pToBeDeleted); pToBeDeleted = NULL; *pHead = NULL; } else // 多个结点,并且删除的是尾结点 { ListNode *curNode = *pHead; while(curNode->m_pNext != pToBeDeleted) // 找到删除结点的前一个结点 curNode = curNode->m_pNext; curNode->m_pNext = NULL; free(pToBeDeleted); pToBeDeleted = NULL; } } ListNode *getNodeIndex(ListNode *pHead, int index) { if(!pHead || index < 0) return NULL; ListNode *node = pHead; while(--index) node = node->m_pNext; return node; } int main(int argc, char const *argv[]) { ListNode *pHead = NULL; createList(&pHead, N); printf("Before: "); printList(pHead); ListNode *pToBeDeleted = getNodeIndex(pHead, 3); deleteNode(&pHead, pToBeDeleted); printf("After: "); printList(pHead); return 0; }
View Code
本文完。
相关文章推荐
- 《一个程序员的生命周期》读后感
- 黑马程序员JAVA笔记1--java基础和概述
- "一个程序员的生命周期"读后感
- 黑马程序员--面向对象
- 黑马程序员——java基础——面向对象的多态
- 读后感for《一个程序员的生命周期》
- 《一个程序员的生命周期》读后感
- 《人,绩效和职业道德》及博客读后感
- 黑马程序员——Java基础:static关键字、单例设计模式
- "一个程序员的生命周期"读后感
- 《C程序员:从校园到职场》出版预告(1):从“高大上”到“柴米油盐”
- 【程序员面试宝典】找规律
- 杂乱的面试题---
- 终于体会到数学对于程序员的魅力
- 构建之法-软件测试+质量保障+稳定和发布阶段+IT行业的创新+人、绩效和职业道德
- 黑马程序员学习日记--反射
- 让程序员跳槽的非钱原因
- 阅读<构建之法>第13、14、15、16、17章 与 《一个程序员的生命周期》读后感
- 我曾经面试过这样一个问题
- 黑马程序员——Java基础——IO输入与输出_3