1.2链表
链表也是一种线性表,他的逻辑结构也是一维的,但它存储的物理结构与顺序表有很大不同。
链表的定义:
链表是将数据元素存放在不连续的地址空间中的一种线性表。链表分为单链表、双链表和循环链表几类。
单链表:
每一个结点包含两部分数据域和下一个结点的地址(指针域)。一个链表通常有一个表头,存放第一个结点的地址。每个结点后面的一个结点称为此结点的后继,链表有一个表尾,表尾没有后继,所以尾指针的指针域为NULL。
单链表具有如下特征:
1.物理位置不一定连续,逻辑上通过指针实现连续
2.有一个头结点和尾结点,并且只有尾结点没有后继结点,其他结点有且仅有一个后继结点。
3.只要知道了链表的头结点,就可以遍历整个链表
链表结构声明如下:
template <typename DataType>class LinkList
{
public:
LinkList()
{
head=new ListNode();
}
LinkList(LinkNode *node)
{
head=node;
}
~LinkList()
{
delete head;
}
bool insertNode(ListNode *q,DataType newData);
bool removeNode(ListNode *q);
ListNode *findNode(DataType value);
bool cleanLink();
DataType getNodeData(ListNode *p);
private:
ListNode *head;
};
链表结点声明如下:
template<typename Datatype> class ListNode
{
public:
ListNode()
{
next=NULL;
}
ListNode(DataType item,ListNode<Datatype> *nextNode=NULL)
{
data=item;
next=nextNode;
}
~ListNode()
{
next=NULL;
}
Datatype getData()
{
return data;
}
ListNode *getNext()
{
return next;
}
private:
friend typename LinkList<DataType>;
DataType *next;
DataType *data;
}
此处设置了两个类,一个是表示结点的LinkNode类,另一个是表示链表整体的LinkList类。在这里我们将LinkList类设为LinkNode的友元类,方便链表类对结点类的内部成员变量和成员方法进行访问。
1.2.2链表的基本操作
操作主要有:
1.插入结点操作
2.删除结点操作
3.查找指定值结点操作
4.清空列表操作
1.插入结点
插入结点操作思路大致如下:
1.创建一个待插入的结点p,为其分配内存空间,并将其指针域设置为NULL。
2.找到单链表的第i个结点位置,获取他的地址q,将结点p插入在结点q与其后继结点之间。
其实现代码如下:
template<typename DataType> bool LinkList<DataType>::insertNode(int i,DataType newData)
{
ListNode<Datatype> *p=head;
int j;
for(j=1;j<=i-1;j++)
{
p=p->next;
if(p==NULL)
{
break;
}
}
if(p==NULL && j<(i-1))
{
std::cout<<"插入位置无效!"<<std::endl;
return false;
}
ListNode<DataType> *node=new ListNode<DataType>(newData);
node->next=p->next;
p->next=node;
return true;
}
那么如何在单链表中添加新结点呢?
template<typename DataType> bool LinkList<DataType>::insertNode(DataType newData)
{
ListNode<DataType> *p=head;
ListNode<DataType> *node=new ListNode<DataType>(newData);
if(node==NULL)
{
return false;
}
while(p->next !=NULL)
{
p=p->next;
}
p->next=node;
return true;
}
2.删除结点
template<typename DataType>bool LinkList<DataType>::removeNode(ListNode<Datatype> *q)
{
if(q==NULL)
{
std::cout<<"待删除结点不存在!"<<std::endl;
return false;
}
LinkNode<DataType> *tempPointer=head;
while(tempPointer->next !=q)
{
tempPointer=tempPointer->next;
}
tempPointer->next=q->next;
delete q;
return true;
}
3.查找特定值结点
template<typename DataType> ListNode<DataType>* LinkList<DataType>::findNode(DataType value)
{
ListNode<DataType> *currentPointer=head;
while(currentPointer!=NULL && currentPointer->data !=value)
{
currentPointer=currentPointer->next;
}
if(currentPointer==NULL)
{
std::cout<<"没有找到该结点!程序异常退出!"<<std::endl;
exit(1);
}
else
{
return currentPointer;
}
}
4.清空链表
template<typename DataType> void LinkList<DataType>::cleanLink()
{
ListNode<DataType> *current =head;
while(head->next !=NULL)
{
current=head->next;
head->next=current->next;
delete current;
}
}