存储结构:
数组是一块连续的内存空间存储的,然而链表是零散的内存空间存储的。
链表在插入和删除操作比数组高效,时间复杂度仅为O(1),链表不是使用连续的内存空间,所以可以充分利用零散的内存空间。
链表结构:
1. 单向链表
2. 双向链表
现在最常见的链表结构:
单向链表、双向链表,下面说一下这几种链表结构的实际操作
1. 单向链表
单向链表插入:找到节点a,在a节点插入节点x,先将x->next指向下一个节点a->next(c节点),再将a->next指向节点x。这里有一个点需要注意,不能先将a->next指向节点x,这样会丢掉节点c的。
单向链表删除:找到节点b前一个节点a,将a->next指向b->next(c节点)
单向链表查找:一个一个节点往下找
实现代码:
template<class T> struct ListNode { T data; ListNode<T>* pNext; ListNode() { pNext = NULL; } }; template<class T> class MyList { public: MyList(); ~MyList(); void InsertListNode(T const& ,int const&); void DeleteListNode(int const&); void ReverseList(); int SeachListNode(T const&) const; int GetListSize() const; ListNode<T>* GetListHeadNode() const; protected: ListNode<T> *pHead; private: }; template<class T> MyList<T>::MyList() { pHead = NULL; } template<class T> MyList<T>::~MyList() { while(pHead != NULL) { ListNode<T>* pTmp = pHead; pHead = pHead->pNext; delete pHead; } } template<class T> void MyList<T>::InsertListNode(T const& param, int const& nPosition) { if(nPosition > GetListSize() + 1) { return ; } ListNode<T>* pInsertNode = new ListNode<T>; pInsertNode->data = param; pInsertNode->pNext = NULL; //List empty if(pHead == NULL) { pHead = pInsertNode; return ; } int nP = nPosition; ListNode<T>* pCurrent = pHead; while(nP>1 && pCurrent->pNext != NULL) { pCurrent = pCurrent->pNext; nP--; } pInsertNode->pNext = pCurrent->pNext; pCurrent->pNext = pInsertNode; } template<class T> void MyList<T>::DeleteListNode(int const& nPosition) { if(pHead == NULL || nPosition > GetListSize()) { return ; } if(nPosition == 1) { ListNode<T>* pTmp = pHead; pHead = pHead->pNext; delete pTmp; return ; } int nP = nPosition; ListNode<T>* pLast = pHead; while(nP>2 && pLast->pNext != NULL) { pLast = pLast->pNext; nP--; } ListNode<T>* pCurrent = pLast->pNext; if(pCurrent != NULL) { pLast->pNext = pCurrent->pNext; } delete pCurrent; } template<class T> int MyList<T>::SeachListNode(T const& param) const { int nPostion = 0; ListNode<T>* pTmp = pHead; while(pTmp) { nPostion++; if(pTmp->data == param) { return nPostion; } pTmp = pTmp->pNext; } return -1; } template<class T> int MyList<T>::GetListSize() const { int nSize = 0; ListNode<T>* pTmp = pHead; while(pTmp != NULL) { nSize++; pTmp = pTmp->pNext; } return nSize; } template<class T> ListNode<T>* MyList<T>::GetListHeadNode() const{ return pHead; }
2.双向链表
双向链表插入:找到节点a,在a节点插入节点x,先将x->next指向下一个节点a->next(b节点),x->prior指向节点a,b->prior指向节点x
双向链表删除:找到节点b,b->prior(节点a)->next指向b->next(节点c),b->next(节点c)->prior指向b->prior(节点a)
双向链表查找:一个一个节点往下找
实现代码:
template<class T> struct DoubleListNode { T data; DoubleListNode<T>* pNext; DoubleListNode<T>* pPrior; DoubleListNode() { pNext = NULL; pPrior = NULL; } }; template<class T> class DoubleList { public: DoubleList(); ~DoubleList(); void InsertDoubleListNode(T const& ,int const&); void DeleteDoubleListNode(int const&); void ReverseDoubleList(); int SeachDoubleListNode(T const&) const; int GetDoubleListSize() const; DoubleListNode<T>* GetDoubleListHeadNode() const; protected: DoubleListNode<T>* m_pHead; private: }; template<class T> DoubleList<T>::DoubleList() { m_pHead = NULL; } template<class T> DoubleList<T>::~DoubleList() { while(m_pHead != NULL) { DoubleListNode<T>* pTmp = m_pHead; m_pHead = m_pHead->pNext; delete pTmp; } } template<class T> void DoubleList<T>::InsertDoubleListNode(T const& param, int const& nPosition) { if(nPosition > GetDoubleListSize() + 1) { return ; } DoubleListNode<T>* pInsertNode = new DoubleListNode<T>; pInsertNode->data = param; pInsertNode->pNext = NULL; pInsertNode->pPrior = NULL; if(m_pHead == NULL) { m_pHead = pInsertNode; return ; } int nP = nPosition; DoubleListNode<T>* pCurrent = m_pHead; while(nP>1 && pCurrent->pNext != NULL) { pCurrent = pCurrent->pNext; nP--; } pInsertNode->pNext = pCurrent->pNext; if(pCurrent->pNext) { pCurrent->pNext->pPrior = pInsertNode; } pCurrent->pNext = pInsertNode; pInsertNode->pPrior = pCurrent; } template<class T> void DoubleList<T>::DeleteDoubleListNode(int const& nPosition) { if(m_pHead == NULL || nPosition > GetDoubleListSize()) { return ; } if(nPosition == 1) { DoubleListNode<T>* pTmp = m_pHead; m_pHead = m_pHead->pNext; m_pHead->pPrior = NULL; delete pTmp; return ; } int nP = nPosition; DoubleListNode<T>* pCurrent = m_pHead; while(nP>1 && pCurrent != NULL) { pCurrent = pCurrent->pNext; nP--; } if(pCurrent != NULL) { DoubleListNode<T>* pLast = pCurrent->pPrior; pLast->pNext = pCurrent->pNext; pCurrent->pNext->pPrior = pLast; } delete pCurrent; } template<class T> int DoubleList<T>::SeachDoubleListNode(T const& param) const { int nPostion = 0; DoubleListNode<T>* pTmp = m_pHead; while(pTmp) { nPostion++; if(pTmp->data == param) { return nPostion; } pTmp = pTmp->pNext; } return -1; } template<class T> int DoubleList<T>::GetDoubleListSize() const { int nSize = 0; DoubleListNode<T>* pTmp = m_pHead; while(pTmp != NULL) { nSize++; pTmp = pTmp->pNext; } return nSize; } template<class T> DoubleListNode<T>* DoubleList<T>::GetDoubleListHeadNode() const { return m_pHead; }
可关注公众号了解更多的面试技巧