赞
踩
单链表是一种常见的简单数据结构,链表由很多个结点组成,每个结点有储存数据的数据域和指向下一个结点的地址。因为每个结点都有下一个结点的地址,因此通过当前结点可以找到下一个结点,将各种数据就像链子一样连接起来。相比于数组,链表的优点就是大小可以改变,删除和插入数据也不必作太大的改动,缺点是不可以随机访问(必须通过一个结点访问下一个结点来访问你想访问的结点)。
//SinglyLink.h
#pragma once
#include <assert.h>
#include <stdio.h>
template<typename ElemType>
class Node
{
public:
Node(Node<ElemType>* pNext = NULL, ElemType* pData = NULL);
ElemType const& GetData() const;
void SetData(ElemType val) ;
Node<ElemType>* const& GetNext() const;
void SetNext(Node<ElemType>* val);
private:
ElemType* m_pData;
Node<ElemType>* m_pNext;
};
template<typename ElemType>
class SinglyLinkList
{
public:
SinglyLinkList();
unsigned int const& GetLength() const;
bool Insert(ElemType elem, unsigned int pos);
bool Delete(unsigned int pos, ElemType* elem);
bool Search(unsigned int pos, ElemType* elem) const;
bool Visit(ElemType* elem, const unsigned int& pos) const;
bool Empty();
private:
Node<ElemType>* m_pHeadNode;
unsigned int m_length;
};
//————————————————————————————————//Node类的实现
template<typename ElemType>
Node<ElemType>::Node(Node<ElemType>* pNext /*= NULL*/, ElemType* pData /*= NULL*/)
:m_pNext(pNext),m_pData(pData)
{
}
template<typename ElemType>
void Node<ElemType>::SetNext(Node<ElemType>* val)
{
m_pNext = val;
}
template<typename ElemType>
Node<ElemType>* const& Node<ElemType>::GetNext() const
{
return m_pNext;
}
template<typename ElemType>
void Node<ElemType>::SetData(ElemType val)
{
m_pData = val;
}
template<typename ElemType>
ElemType const& Node<ElemType>::GetData() const
{
return *m_pData;
}
//————————————————————————————————//SinglyLink类实现
template<typename ElemType>
SinglyLinkList<ElemType>::SinglyLinkList()
:m_pHeadNode(new Node<ElemType>()),m_length(0)
{
}
template<typename ElemType>
bool SinglyLinkList<ElemType>::Insert(ElemType elem, unsigned int pos)
{
if (pos > GetLength() || pos < 0)
{
assert(false && "Error: SinglyLink's insert pos is out of range!\n");
return false;
}
for(Node<ElemType>* pCurrentNode = m_pHeadNode; pCurrentNode != NULL; pCurrentNode = pCurrentNode->GetNext())
{
if (pos-- == 0)
{
Node<ElemType>* insertNode = new Node<ElemType>(pCurrentNode->GetNext(),new ElemType(elem));
pCurrentNode->SetNext(insertNode);
++m_length;
return true;
}
}
assert(false && "Error: SinglyLink Insert failed for unknow reason!");
return false;
}
template<typename ElemType>
bool SinglyLinkList<ElemType>::Delete(unsigned int pos, ElemType* elem)
{
if (pos >= GetLength() || pos < 0)
{
assert(false && "Error: SinglyLink's delete pos is out of range!\n");
}
for(Node<ElemType>* pCurrentNode = m_pHeadNode; pCurrentNode != NULL; pCurrentNode = pCurrentNode->GetNext())
{
if (pos-- == 0)
{
Node<ElemType>* deleteNode = pCurrentNode->GetNext();
pCurrentNode->SetNext(deleteNode->GetNext());
*elem = deleteNode->GetData();
delete deleteNode;
--m_length;
return true;
}
}
assert(false && "Error: SinglyLink pos delete failed for unknow reason!");
return false;
}
template<typename ElemType>
unsigned int const& SinglyLinkList<ElemType>::GetLength() const
{
return m_length;
}
template<typename ElemType>
bool SinglyLinkList<ElemType>::Search(unsigned int pos, ElemType* elem) const
{
if (pos >= GetLength() || pos < 0)
{
assert(false && "Error: SinglyLink's search pos is out of range!\n");
}
for(Node<ElemType>* pCurrentNode = m_pHeadNode; pCurrentNode != NULL; pCurrentNode = pCurrentNode->GetNext())
{
if (pos-- == 0 && (pCurrentNode->GetNext() != NULL) )
{
*elem = pCurrentNode->GetNext()->GetData();
return true;
}
}
return false;
}
template<typename ElemType>
bool SinglyLinkList<ElemType>::Visit(ElemType* elem, const unsigned int& pos) const
{
if (pos >= GetLength() || pos < 0)
{
return false;
}
return Search(pos,elem);
}
template<typename ElemType>
bool SinglyLinkList<ElemType>::Empty()
{
return !m_length;
}

//Util.h
#pragma once
namespace Util
{
template<typename T>
void PrintMemory(const T& dateStruct, unsigned int size)
{
cout << "PrintMemory: ";
for (int i = 0; i != size; i++)
{
ElemType tempElem;
if (!dateStruct.Visit(&tempElem,i))
{
printf("\n");
return;
}
printf("%d ",tempElem);
}
printf("\n");
}
}

//main.cpp
#include "Util.h"
#include "SinglyLinkList.h"
#include <iostream>
using namespace std;
typedef int ElemType;
int main()
{
SinglyLinkList<int> testSinglyLinkList;
cout << "testSinglyLinkList is " << (testSinglyLinkList.Empty() ? "Empty." : "Not Empty.") << endl;
Util::PrintMemory(testSinglyLinkList,testSinglyLinkList.GetLength());
for (int i = 0; i != 5; i++)
{
testSinglyLinkList.Insert(i+1,i);
cout << "\nInsert:" << i+1 << endl;
cout << "testSinglyLinkList is " << (testSinglyLinkList.Empty() ? "Empty." : "Not Empty.") << endl;
Util::PrintMemory(testSinglyLinkList,testSinglyLinkList.GetLength());
}
for (int i = 0; i != 2; i++)
{
ElemType tempElem;
testSinglyLinkList.Delete(i,&tempElem);
cout << "\nDelete:" << tempElem << endl;
cout << "testSinglyLinkList is " << (testSinglyLinkList.Empty() ? "Empty." : "Not Empty.") << endl;
Util::PrintMemory(testSinglyLinkList,testSinglyLinkList.GetLength());
}
return 0;
}

testSinglyLinkList is Empty.
PrintMemory:Insert:1
testSinglyLinkList is Not Empty.
PrintMemory: 1Insert:2
testSinglyLinkList is Not Empty.
PrintMemory: 1 2Insert:3
testSinglyLinkList is Not Empty.
PrintMemory: 1 2 3Insert:4
testSinglyLinkList is Not Empty.
PrintMemory: 1 2 3 4Insert:5
testSinglyLinkList is Not Empty.
PrintMemory: 1 2 3 4 5Delete:1
testSinglyLinkList is Not Empty.
PrintMemory: 2 3 4 5Delete:3
testSinglyLinkList is Not Empty.
PrintMemory: 2 4 5
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。