雙向迴圈連結串列 ---- C++使用類模板實現
阿新 • • 發佈:2019-01-07
//雙向迴圈連結串列類模板
template <typename T>
class DLinkList
{
public:
DLinkList();
DLinkList(T elem);
DLinkList(int n, T elem);
~DLinkList();
void ClearList() const;
bool Empty() const;
int Length() const;
T GetElem(int n) const;
int LocateElem(T elem) const;
bool Insert(int n, T elem);
bool Delete(int n);
void Displasy();
void DisplasyL();
void Remove(T elem);
private:
DLNode<T> *m_head;
};
template <typename T>
DLinkList<T>::DLinkList()
{
//建立頭節點
m_head = new DLNode < T > ;
if (nullptr == m_head)
{
cout << "動態申請頭節點記憶體失敗" << endl;
return;
}
m_head->next = m_head;
m_head->prior= m_head;
}
template <typename T>
DLinkList<T>::DLinkList(T elem) :DLinkList()
{
Insert(1, elem);
}
template <typename T>
DLinkList<T>::DLinkList(int n, T elem) :DLinkList()
{
for (int i = 0; i < n; ++i)
{
Insert(i, elem);
}
}
template <typename T>
DLinkList<T>::~DLinkList()
{
ClearList(); //置為空白
delete m_head; //釋放頭節點
}
template <typename T>
void DLinkList<T>::ClearList() const //常成員函式 不改變物件的值
{
DLNode<T> *temp, *p = m_head->next;
while (p != m_head) //刪除頭節點以後的所有節點
{
temp = p->next;
delete p; //要釋放動態記憶體
p = temp;
}
m_head->next = m_head;
m_head->prior = m_head;
}
template <typename T>
bool DLinkList<T>::Empty() const
{
//如果頭節點的下一個節點為空,則該連結串列為空
return m_head == m_head->next;
}
template <typename T>
int DLinkList<T>::Length() const
{
int count = 0;
DLNode<T> *ptemp = m_head->next;
while (ptemp != m_head)
{
count++;
ptemp = ptemp->next;
}
return count;
}
template <typename T>
T DLinkList<T>::GetElem(int n) const
{
DLNode<T> *ptemp = m_head->next;
if (n <= Length())
{
for (int i = 1; i < n; ++i)
{
ptemp = ptemp->next;
}
}
else
{
cout << "out of ranger" << endl;
return false;
}
return ptemp->data;
}
template <typename T>
int DLinkList<T>::LocateElem(T data) const
{
size_t location = 0;
DLNode<T> *ptemp = m_head->next;
while (ptemp != m_head)
{
++location;
if (ptemp->data == data) //注意 該型別必須支援 == 操作符,如果不支援需要進行運算子過載
{
return location;
}
ptemp = ptemp->next;
}
return 0; //返回0表示未找到
}
template <typename T>
bool DLinkList<T>::Insert(int n, T elem)
{
DLNode<T> *ptemp = m_head;
if (n - 1 <= Length())
{
for (int i = 0; i < n - 1; ++i)
{
ptemp = ptemp->next;
}
//先生成一個新的節點
DLNode<T> *newnode = new DLNode < T >;
if (nullptr == newnode)
{
cout << "申請空間失敗" << endl;
return false;
}
newnode->data = elem; //如果資料型別不是基本資料型別,即不支援 = 操作符,需要過載 = 操作符
newnode->next = ptemp->next;
newnode->prior = ptemp;
ptemp->next->prior = newnode;
ptemp->next = newnode;
return true;
}
else
{
cout << "out of range" << endl;
return false;
}
}
template <typename T>
bool DLinkList<T>::Delete(int n)
{
DLNode<T> *ptemp = m_head;
if (n <= Length())
{
for (int i = 0; i < n - 1; ++i)
{
ptemp = ptemp->next;
}
DLNode<T> *t = ptemp->next; //指向待刪除的節點
ptemp->next = ptemp->next->next; //將待刪除節點的上一節點指向待刪除節點的下一節點
ptemp->next->next->prior = ptemp;
delete t; //釋放刪除節點的記憶體
return true;
}
else
{
cout << "out of range" << endl;
return false;
}
}
template <typename T>
void DLinkList<T>::Displasy()
{
DLNode<T> *ptemp = m_head->next;
while (ptemp != m_head)
{
cout << ptemp->data << " ";
ptemp = ptemp->next;
}
cout << endl;
}
template <typename T>
void DLinkList<T>::DisplasyL()
{
DLNode<T> *ptemp = m_head->prior;
while (ptemp != m_head)
{
cout << ptemp->data << " ";
ptemp = ptemp->prior;
}
cout << endl;
}
template <typename T>
void DLinkList<T>::Remove(T elem)
{
DLNode<T> *ptemp = m_head;
while (ptemp->next != m_head)
{
if (ptemp->next->data == elem) //找到與要刪除的節點相同
{
DLNode<T> *t = ptemp->next; //指向待刪除的節點
ptemp->next = ptemp->next->next; //將待刪除節點的上一節點指向待刪除節點的下一節點
delete t; //釋放刪除節點的記憶體
}
else //這裡需要注意一下:如果刪除了那麼它的下一節點是新的節點需要重現判斷,所以不需要移動
{
ptemp = ptemp->next;
}
}
}
測試程式:
int main()
{
DLinkList<string> DLink( 10, "hahah");
DLink.Insert(1, "zjy");
DLink.Delete(2);
DLink.Displasy();
DLink.Remove("hahah");
DLink.Displasy();
system("pause");
return 0;
}
執行結果: